2

I am brand new to programming and working through Proj Euler with Ruby. Why wont this ruby loop break?

(1..5).each do |a|
  (1..5).each do |b|
    e=(a*a)+(b*b)
    c=Math.sqrt(e)
    puts "a=#{a}, b=#{b}, c=#{c}"
    break if a+b+c == 12
  end
end

Note if I put anything else in the if statement (say puts "found it" if a+b+c == 12) it works just fine, it just won't break

lemonginger
  • 345
  • 2
  • 17
  • It is in the inner range loop and breaks that, but the outer loop will continue. – squiguy Apr 10 '13 at 07:05
  • 2
    possible duplicate of [How to break outer cycle in Ruby?](http://stackoverflow.com/questions/1352120/how-to-break-outer-cycle-in-ruby) – pdu Apr 10 '13 at 07:05
  • your question is confusing. Why you are saying to run your code in our terminal. Rather you could give the output here and asks from that output the unexpected behavior you found and what should be the expected output. – Arup Rakshit Apr 10 '13 at 07:09
  • Yes, I meant to delete see output because I figured it didn't need to be pasted in. Thanks for the loop hint, I didn't know break only broke out of one loop. I used throw:error instead and it worked fine, though seems a bit clunky, but onto the next problem! I will accept the answer that says how to do this a "proper" way (since it's not really an error I am looking for and maybe I don't want to exit the entire program, just these nested loops – lemonginger Apr 10 '13 at 07:11
  • I added the right way to do this (this is a possible duplicate of : http://stackoverflow.com/questions/1352120/how-to-break-outer-cycle-in-ruby ) – halflings Apr 10 '13 at 07:21

3 Answers3

3

It's normal because you only break from the loop on b. (the loop keeps going on a)


The right way to do this is described in this question : How to break outer cycle in ruby

Community
  • 1
  • 1
halflings
  • 1,540
  • 1
  • 13
  • 34
1

The code below may what you want to do

(1..5).each do |a|
  break unless (1..5).each do |b|
    e=(a*a)+(b*b)
    c=Math.sqrt(e)
    puts "a=#{a}, b=#{b}, c=#{c}"
    break if a+b+c == 12
  end
end

when break is triggered in the loop, the return value of the loop become break value, which is nil in this case. In other case, (1..5) is returned. So this code will work.

Naoyoshi Aikawa
  • 1,135
  • 10
  • 16
1

As other said, break will only end the inner loop.

You could rewrite your code, for example like this:

[*1..5].product([*1..5]).map{|a, b| [a, b, Math.sqrt(a*a+b*b)]}.each do |a, b, c|
    puts "a=#{a}, b=#{b}, c=#{c}"
    break if a + b + c == 12
end

Now, break will work as you expected.

maro
  • 1,506
  • 13
  • 21