tags:

views:

67

answers:

4

I am trying to find the factors of a number N. I want to be able to iterate over my prime numbers array, and when a condition is met, go back to start of the iteration, rather than just continuing on.

arrFactors = []    
N = 150
[2,3,5,7,11].each do |a|
  if N % a == 0
    arrFactors.push(a)
    N = N/a
    break if N == 1
    <return to start of the collection [2,3,5,7,11]>
  end
end

How can I do this in Ruby 1.8.6? (I notice there is a "cycle" enumerator in 1.8.7 that maybe relavent?)

P.S
I know the below algorithm is not perfect yet (I think I need to provide for N = 1). I also know Ruby provides a factoring method, but I don't want to use 'cause I'm learning here.

+2  A: 

you could use something like that:

[2,3,5,7,11].each do |a|

  while N % a == 0
    arrFactors.push(a)
    N = N/a
  end

  if N == 1 then
    break
  end

end

This would remove the need to reset the outer loop.

Engin Kurutepe
This solves my problem, but does it answer my main question of resetting the loop? It works only because it appears the factors don't jump around when dividing. In other words, factors won't come in the order 2, 5, 2, 7 (140/2 = 70/2 = 35/5 = 7). But if I wanted to reset the loop in some other hypothetical problem, is there a Ruby enumerator or other that would do it?
b1_
I am not 100% sure but I think this is not possible with an each loop. You can achieve more direct control on the array by defining an array_index setting it as necessary inside a while-loop. old school, yes, but gives you more direct control.
Engin Kurutepe
+2  A: 

Rather than use the Array.each method, you could look into using the Array.select method. This method takes a block, and will return a new array with only the items that match your logic. If your block returns true, then that item will be included in the result set. The following code uses the select method and does what you're looking for:

[2,3,5,7,11].select do |a|
  if N % a == 0
    N = N/a
    break if N == 1
    return true
  end
  return false
end

The documentation for the select method can be found here.

Mike Trpcic
A: 

"redo" resets the loop current iteration of the loop. "retry" would start the loop all over. (Oh, and "N" is a constant; should be "n".)

steenslag
No, it doesn't. It resets the *current iteration* of the loop.
Jörg W Mittag
You are right. Will edit the answer.
steenslag
A: 

You can try this

n = 150
factors = [2,3,5,7,11]
arrFactors = []
factor_index = 0
  while ((factors.size > factor_index + 1) || n > 1) do
    factors.each_with_index { |f, i|      
      factor_index = i
      if (n % f) == 0
        arrFactors.push(f)
        n = n / f 
        break
      end
    }
  end
puts n
puts arrFactors
Tumtu