views:

219

answers:

4

Hi guys,

I solved a problem recently. But I have this one piece of code where I dont utilize the for loop initialization and condition check. It looks a bit odd that way for a for loop. I want to convert it into a while loop. Please help me do it. I tried many times, but somewhere something is missing.

for(;;current =(current+1)%n){
    if(eliminated[current%n]){
        continue;
    }else{
        inkiPinki++;
        if(inkiPinki == m){
            eliminated[current%n] = true;
            printStatus(eliminated, people);
            remainingGuys--;
            break;
        }
    }
}

In the above code eliminiated[index] is a boolean.

Edit: Thanks to Geoff who provided me with a solution which I further minimized like this.

while( eliminated[current] || ++inkiPinki != m )
    current = (current+1) % n;
eliminated[current] = true;
printStatus( eliminated, people );
remainingGuys--;
+1  A: 

Try

while( true ) {
    if( !eliminated[current] ) {
        if( ++inkiPinki == m ) {
            break;
        }
    }
    current = (current+1) % n;
}
eliminated[current] = true;
printStatus( eliminated, people );
remainingGuys--;

It should be logically equivalent.

Geoff
This i tried, but the last line current = (current+1)%n execution wont happen if it encounters continue
Bragboy
Yeah, sorry, I fixed it.
Geoff
Hi, Please see my EDIT
Bragboy
Do you just mean that you want printStatus outside the loop?
Geoff
Revised the answer a little, it's pretty simple now, I don't see that any more needs/wants removed from it.
Geoff
Yep, its working now!! Thanks.. i guess it can be further reduced.. Thank you anyway, i will take from here
Bragboy
while( eliminated[current] || ++inkiPinki != m ) current = (current+1) % n; eliminated[current] = true; printStatus( eliminated, people ); remainingGuys--;
Bragboy
Thank you Geoff!
Bragboy
+1  A: 

How I would do it:

while (inkiPinki < m) {
    if (!eliminated[current % n]) {
        inkiPinki++;

        if (inkiPinki == m) {
            eliminated[current % n] = true;
        }
    }

    if (inkiPinki < m) {
        current = (current + 1) % n;
    }
}

printStatus(eliminated, people);
remainingGuys--;

This code accomplishes exactly the same thing as your original for loop, except it uses logical tests to determine whether or not it should continue to loop. There's no need for continue or break. If you find yourself using either of these statements, there's probably some refactoring that should be done.

Christopher Parker
Tried your code. Its not working.
Bragboy
Can you please qualify "it's not working"? Also, could you please try again, with the current revision?
Christopher Parker
Hi, i tried now still its failing.. Thank you for your efforts
Bragboy
It also doubles up the exit test, which is error prone (and inefficient, at the risk of being accused of premature optimization).
Software Monkey
+2  A: 

All for loops can be converted to while loops using the following pattern:

for (..xxx..; ..yyy..; ..zzz..) {
  ..aaa..
}

becomes

...xxx...
while (...yyy...) {
  ..aaa..
  ..zzz..
}

remember that

for (;;) {
  ..aaa..
}

is equivalent to

for (nop; true; nop) {
  ..aaa..
}

where "nop" means no operations.

In your example this makes your loop:

for(;;current =(current+1)%n){
    if(eliminated[current%n]){
        continue;
    }else{
        inkiPinki++;
        if(inkiPinki == m){
            eliminated[current%n] = true;
            printStatus(eliminated, people);
            remainingGuys--;
            break;
        }
    }
}

equivalent to

// no initialzation needed
while(true) {
    //if(eliminated[current%n]){
    //    continue;
    //}else{
    if(!eliminated[current%n]){
        inkiPinki++;
        if(inkiPinki == m){
            eliminated[current%n] = true;
            printStatus(eliminated, people);
            remainingGuys--;
            break;
        }
    }
    current =(current+1)%n;
}

From there, you can simplify it further, if you wish.

Edwin Buck
doesn't the 'continue' in the loop body break your transformation?
Mr. Shiny and New
Gotta watch that continue doesn't cause a skip in updating when transforming a for to another loop; I corrected the code, because with it corrected it's the best answer, since it most closely resembles the original and I wanted to upvote it.
Software Monkey
Thanks for the update. Yes, the continue in the loop body broke the transformation. I must have needed an extra cup of coffee when I was writing that one, and thanks again for the correction.
Edwin Buck
A: 

I seem to have an inordinate fondness for using Booleans as integers:

for (;inkiPinki<m; inkPinki += !eliminated[current])
    current = (current + 1) %n;

eliminated[current] = true;
printStatus(eliminated, people);
remainingGuys--;

I've also changed current%n to simply current in a couple of places, because the %n is already done where current is incremented, so current should already be reduced modulo n.

If I were doing it, I'd probably change the sense, so instead of eliminated, it was something like remaining:

for (;inkiPinki<m; inkPinki += remaining[current])
    current = (current + 1) %n;

remaining[current] = false;
printStatus(remaining, people);
remainingGuys--;
Jerry Coffin