views:

497

answers:

12

hey I'm looking for are clean solution to this problem:

alt text

i start the loop with i = 0 in the second loop step the i = 1, then i = -1 and then i = 2 ect.

how to programm this with a for loop in a clean way?

+10  A: 

If you don't mind having the inner loop appear 3 times:

f(0);
for (var i = 1; i <= 3; ++ i) {
  f(i);
  f(-i);
}

2 times with an if:

for (var i = 0; i <= 3; ++ i) {
  f(i);
  if (i > 0)
     f(-i);
}

single time but with an ugly expression:

for (var j = 1; j <= 7; ++ j) {
   var i = j / 2;
   if (j % 2) i = -i;

   f(i);
}
KennyTM
thanks, i like the "ugly expression" version the most :)
antpaw
@antpaw whhhhhyyyyyyyyy? Aside from being ugliest, it's the most convoluted and inefficient one as well in terms of processing.
@Kenny +1. Another possible, solution, and this may even be required if we didn't have random access but only bidirectional access to a linked list, e.g., is to use two iterators (one gets decremented, other gets incremented, and accessing the first element at the beginning).
you could even "improve" it to `j/2 * -((j%2) * 2 - 1)`
peterchen
+27  A: 
f(0); //do stuff with 0

for(var i = 1; i<len; i++) //where len = positive boundary
{
    f(i);  //do stuff with i
    f(-i); //do stuff with -i
}

Should do what you want

FallingBullets
+1 for elegance in form; you might have to extract do_stuff into a separate function in order to avoid code duplication, but otherwise it's pretty beautiful.
Justin L.
+1, for simplicity
Robin Day
-1, for simplicity
mario
This isn't valid JavaScript or PHP. `var`, not `int`.
Tim Down
+5  A: 

Each loop, you appear to be adding n*(-1)^(n+1), where n is the step you are currently taking, starting at 1, and starting at i=0.

initialize i = 0
n=0, i+=0*(-1)^1   # 0
n=1, i+=1*(-1)^2   # 1
n=2, i+=2*(-1)^3   # -1
n=3, i+=3*(-1)^4   # 2

etc.

From here, it depends on what language you would wish to write in. Iterate from n = 0 to wherever you are stopping.

edit this is a bad answer. but fun =D

(I added that last bit because as soon as I made that edit, someone downvoted me =( )

Justin L.
+1 This was my immediate thought for an answer as well :)
SLC
+3  A: 

Here is implementation in javascript

for ( var i = 0; Math.abs(i)<10; i=(i<=0?Math.abs(i)+1:-i)) {
  console.debug(i) 
}

Hope it helps.

Alexey Ogarkov
hehe nice skills :)
antpaw
+1  A: 
        for (int i = 0; i < 10; i++)
        {
            int div = i / 2;
            int mod = i % 2;

            int offset = mod == 0 ? div : -div;
        }
Robin Day
+2  A: 

I used the sine function:

for ($i = 0; $i < 10; $i++)
{
    echo round(0.5 * $i * sin((0.5 + $i) * M_PI))."\n";
}
Sjoerd
A: 

A modification of falling bullet's solution, that will handle the 0 index case without a special condition.

//do stuff with 0
for(int i = 0; i< (arrayLength/2); i++)
{
    //do stuff with i

    if(-i != i)
    {
        //do stuff with negIndex
    }
}
Tom Gullen
+1  A: 

There is a pattern to this loop. Looking at it on the number line - it goes like:

  • 0 steps backward
  • 1 step forward
  • 2 steps backward
  • 3 steps forward
  • 4 steps backward

Here's one solution - keep incrementing the step size in each iteration of the loop, and flip direction (forward/backward) every time. Keep adding to the current value.

// n is the number of elements to generate
for(var i = 0, value = 0, dir = -1; i < n; i++) {
    value = value + (dir * i);
    console.log(value);
    dir = dir * -1; // reverse direction
}

Another solution using generators in JavaScript 1.7 which is identical to @FallingBullet's solution but more aesthetically pleasing to my eye :)

function sequence() {
    var i = 0;

    yield i;

    while(true) {
        i++;
        yield i;
        yield -i;
    }
}


var seq = sequence();
seq.next(); // 0
seq.next(); // 1
seq.next(); // -1
seq.next(); // 2
...
Anurag
A: 

In C. The value of N is the total number of values in the sequence you wish to yield.

int i, n = 0, m = 1;
for (i = 1; i < N; i++, m = -m) {
    /* n is the next in the sequence */
    n += m * i;
}
bjg
+3  A: 

Just one addition one subtraction and a negation:

for(int i=0, d=1, f=-1; i<10; i+=d, d=f-d, f=-f)
{
    printf("%d\n", i);
}

generates an inner loop of:

push        esi  
push        offset string "%d\n" (0D20F4h)  
call        dword ptr [__imp__printf (0D20A4h)]  
mov         eax,ebx  
add         esi,edi  
sub         eax,edi  
add         esp,8  
neg         ebx  
mov         edi,eax  
cmp         esi,0Ah  
jl          wmain+10h (0D1010h)  
cskilbeck
+1  A: 

For what it's worth, here is my own interpretation of the problem.

for (var i = 0; i > -8; i = (i<=0) - i) // arbitrary condition stops loop at -8
salathe
A: 

I'd probably go with:

for (var i = 0; i <= max; i = ( i <= 0 ) ? -i + 1 : -i)
{
    f( i );
}
Jake