Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a nested loop with Ruby the "Right Way!"?

I'm in the process of learning Ruby, taking a Berkeley's MOOC, and, in some of these MOOC's homework we have an exercise that says:

Define a method sum_to_n? which takes an array of integers and an additional integer, n, as arguments and returns true if any two elements in the array of integers sum to n. An empty array should sum to zero by definition.

I already created two methods that can do the job, but I'm not comfortable with any of them because I think they are not written in the Ruby Way. I hope some of you can help me to learn which would be the right way!

The first method I made uses the each method for both iterations, but what I don't like about this method is that every number is summed with every other number, even with the same number, doing something like this:

arr[1, 2, 3, 4] => 1+1, 1+2, 1+3, 1+4, 2+1, 2+2, 2+3, 2+4, 3+1, 3+2... 4+3, 4+4

As you can see, there's a lot of repeated sums, and I don't want that.

This is the code:

def sum_to_n?(arr, n)
  arr.each {|x| arr.each {|y| return true if x + y == n && x != y}}
  return true if n == 0 && arr.length == 0
  return false
end

With the other method I got what I wanted, just a few sums without repeating any of them or even summing the same numbers, but it looks HORRIBLE, and I'm pretty sure someone would love to kill me for doing it this way, but the method does a great job as you can see:

arr[1, 2, 3, 4] => 1+2, 1+3, 1+4, 2+3, 2+4, 3+4

This is the code:

def sum_to_n?(arr, n)
  for i in 0..arr.length - 1
    k = i + 1
    for k in k..arr.length - 1
      sum = arr[i] + arr[k]
      if sum == n
        return true
      end
    end
  end
  return true if n == 0 && arr.length == 0
  return false
end

Well, I hope you guys have fun doing a better and prettier method as I did trying.

Thank you for your help.

like image 662
David Gomez Avatar asked Oct 15 '13 00:10

David Gomez


People also ask

How do you create nested loops?

A nested loop is a loop within a loop, an inner loop within the body of an outer one. How this works is that the first pass of the outer loop triggers the inner loop, which executes to completion. Then the second pass of the outer loop triggers the inner loop again. This repeats until the outer loop finishes.

What rules apply to nested loops?

In a nested loop, a break statement only stops the loop it is placed in. Therefore, if a break is placed in the inner loop, the outer loop still continues. However, if the break is placed in the outer loop, all of the looping stops.

What is an example of a nested loop?

Here's an example of the nested for loop. // outer loop for (int i = 1; i <= 5; ++i) { // codes // inner loop for(int j = 1; j <=2; ++j) { // codes } .. } Here, we are using a for loop inside another for loop. We can use the nested loop to iterate through each day of a week for 3 weeks.

How to print a pattern using nested while loop in Ruby?

In Ruby, Nesting of the while loop can be done with the help of the following syntax: while (condition ) while (condition ) # code to be executed end #expressions end We can print various patterns using nested while loops. Let us see how the following pattern can be printed.

What is the right way to iterate through an array in Ruby?

What is the "right" way to iterate through an array in Ruby? PHP, for all its warts, is pretty good on this count. There's no difference between an array and a hash (maybe I'm naive, but this seems obviously right to me), and to iterate through either you just do array.length.times do |i| end array.each array.each_index for i in array

What is the meaning of nested for loop?

Nesting of for loop means one for loop is available inside another for loop. It means that there are two loops, then the first one is an outer loop and the second one is the inner loop.

How do I get the value of an array in Ruby?

foreach (array/hash as $key => $value) In Ruby there are a bunch of ways to do this sort of thing: array.length.times do |i| end array.each array.each_index for i in array Hashes make more sense, since I just always use


Video Answer


2 Answers

I'd write it like this:

def sum_to_n?(arr, n)
  return true if arr.empty? && n.zero?
  arr.combination(2).any? {|a, b| a + b == n }
end

That seems to be a pretty Rubyish solution.

like image 81
Jörg W Mittag Avatar answered Oct 22 '22 21:10

Jörg W Mittag


I came across this on CodeWars. The accepted answer sure does look very Rubyish, but that is at the cost of performance. Calling arr.combination(2) results in a lot of combinations, it'd be simpler to go over the array element by element and search whether the 'complement' sum - element exists. Here's how that'd look like -

def sum_to_n?(arr, n)
  (arr.empty? and n.zero?) or arr.any? { |x| arr.include?(n - x) }
end
like image 45
rohitpaulk Avatar answered Oct 22 '22 19:10

rohitpaulk