5

I want to set the first least common multiple of 2 number(n1 and n2), but my break statement won't work. I don't want to use a return(which it works). Is there a way to work around this? Thanks.

var firstDayTogether,n1,n2;

for(var i=1;i<12345;i++){
    for(var j=1;j<12345;j++){
        if((s1*i)==(s2*j)){
            firstDayTogether=(s1*i);
            break;
        }
    }
}
Ming Huang
  • 1,310
  • 3
  • 16
  • 25
  • 7
    Break statement only breaks one loop. – jyvet Jan 15 '16 at 18:46
  • You have nested loops, do you want to break out of both loops simultaneously? – Saqib Amin Jan 15 '16 at 18:46
  • the break statement will only break you out of inner for loop. If you want to break out of outer one too, simply use return...or break the second for loop too by checking for a condition and using break again – Rash Jan 15 '16 at 18:46
  • 5
    http://stackoverflow.com/questions/183161/best-way-to-break-from-nested-loops-in-javascript – dtanders Jan 15 '16 at 18:46
  • 2
    i think you should use a more efficient algo: https://en.wikipedia.org/wiki/Least_common_multiple – Fabricator Jan 15 '16 at 18:48

3 Answers3

21

You're only breaking out of the inner loop. You can use a label to specify which loop to end.

outerloop: for( var i=1; i<12345; i++) {
    for( var j=1; j<12345; j++) {
        if((s1*i)==(s2*j)) {
            firstDayTogether = s1*i;
            break outerloop; // <== !!
        }
    }
}
user2864740
  • 60,010
  • 15
  • 145
  • 220
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 1
    This is super-cool. Can you add some explanation of what this does / how it works? – random_user_name Jan 15 '16 at 18:48
  • 1
    haven't seen labels in javascript in a long time. +1 – AtheistP3ace Jan 15 '16 at 18:48
  • 1
    I don't know why "not seeing something in a long time" is a +1: usually not seeing something means there are better alternatives.. that being said, it does explain the problem and offer a minimal solution (which *may* be most suitable). – user2864740 Jan 15 '16 at 18:48
  • 1
    Well sir, since you are interested I'll explain. They were two separate things. I liked his answer. And I commented on something I hadn't seen in a long time. – AtheistP3ace Jan 15 '16 at 18:49
  • 1
    This labeling concept is super awesome. I followed your steps and found reference to this is anyone is interested to look into it more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label – Ming Huang Jan 15 '16 at 19:16
2

As noted in comments, break only breaks from the loop it is in. It does not break out of outer layers of nested loops.

Put your nested loops into a function, then you can naturally return the result when you find it.

var firstDayTogether,n1,n2;

function findFirst(s1, s2) {
    for(var i=1;i<12345;i++){
        for(var j=1;j<12345;j++){
            if((s1*i)==(s2*j)){
                return (s1*i);
            }
        }
    }
}

firstDayTogether = findFirst(n1, n2);
dsh
  • 12,037
  • 3
  • 33
  • 51
1

There are ways to make this more efficient:

  • The first one is to directly test for divisibility, n2 has to be a divisor of the LCM n1*i, so that there is only one loop and no label needed:

    for ( var i=1; i<12345; i++) {
        if((n1*i) % n2 == 0) {
            firstDayTogether = n1*i;
            break;
        }
    }
    
  • The second improvement is to apply mathematics in that

    LCM(n1,n2) = n1·n2 / GCD(n1,n2)

    and for the GCD you can use your preferred variant of Euclids algorithm.

    var a=n1;
    var b=n2;
    while(b!=0){ var r=a%b; a=b; b=r; }
    firstDayTogether = n1*n2/a; 
    

First variant even shorter, without break:

    var i;
    for (i=1; (n1*i) % n2 != 0; i++) { }
    firstDayTogether = n1*i;
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • 1
    Your last code snippet does not produce the same output as your first. The last one should much rather read: `var i; for (i=1; (n1*i) % n2 != 0; i++) { } firstDayTogether = n1*i;` – morido Jan 15 '16 at 23:49
  • You are right, the result contains one step before the LCM. Edited with yet another variant. – Lutz Lehmann Jan 16 '16 at 00:04
  • After your edit its not much better. Consider the case of `n1 == n2`. And why do you actually have to reassign `firstDayTogether` inside the loop's body all the time? Intermediate results aren't of interest (and counteract your efficiency goal). – morido Jan 16 '16 at 00:10
  • Okay, another fix. One should never ignore the trivial test cases. I'm just stubborn to keep `i` local to the loop. For an actual implementation I would use the GCD method. – Lutz Lehmann Jan 16 '16 at 00:19
  • Now your condition in the first iteration essentially reads `0 % n2 != 0` and this is [always false](http://math.stackexchange.com/questions/111330/explain-for-students-why-does-0-mod-n-equals-0-zero) regardless of the value of `n2`. In other words: Still doesn't work. What's so bad with having `i` external to the loop actually? In ANSI C that's the normal way... – morido Jan 16 '16 at 00:34
  • Must you send out all those negative vibrations? Before it gets too ridiculous I'll adopt your, now much simpler, solution. – Lutz Lehmann Jan 16 '16 at 00:39
  • Sorry, I didn't mean to offense you. I'm simply enjoying my little victory over someone who appears to be a professional mathematician (a subject where I am usually especially bad at). :-) I'll donate you an upvote for "compensation", ok? – morido Jan 16 '16 at 00:52
  • Thanks. And it was not at all offensive. Only an accumulations of too many pitfalls. – Lutz Lehmann Jan 16 '16 at 00:55