2

Using modular arithmetic (or) (%) operator in C++ we can cycle through the successive numbers with a range.

For example:

if range is 5 (or) modulo 5 then we can cycle through

0 1 2 3 4 0 (5) 1(6) 2(7) 3(8) 4(9) 0(10)............0 1 2 3 etc.

Question:

In the similar sense is there any arithmetical relation / C++ trick we can use to move increasing numbers in forward(till upper bound) and decreasing numbers in reverse direction(till lower bound or 0) with a range.

For example:

if range = 5 then

0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0.....................0 1 2 3 etc.

In the below program I used two approaches to iterate forward/reverse within a given range.

But I'm interested in- Is there any best way (C++ trick/Mathematical relation) of iterate through forward and reverse within a given range ?.

#include<iostream>
int main() {
    int range = 5;

    // 0 1 2 3 4 0 1 2 3 4 .....(Cycle through in the range 0 - 4)
    int i = 0;
    while(true) {
        // 0 1 2 3 4 0 1 2 3 4 .....(cycle through in the range 0 - 4)
        std::cout<< i; 
        i = (i+1)% range; // Modulo
        // some break condition
    }

    // 0 1 2 3 4 3 2 1 0 .......... (Forward and Reverse in the range 0 - 4)
    // Method 1:
    int j = 0;
    bool reverse = false;
    while(true) {
        if(reverse == false) {
            if(j < range) {
                std::cout << j;
                j = j+1;
            }
            else {
                reverse = true;
                j = j-1;
            }
        }
        else {
            j = j-1;
            std::cout << j;
            if(j == 0) {
                reverse = false;
                j = j + 1;
            }
        }
        // some break condition
    }

    // 0 1 2 3 4 3 2 1 0 .......... (Forward and Reverse in the range 0 - 4)
    // Method 2: 
    // Using modulo (if the range is big value then this is not good approach)
    int limit[8] = {0,1,2,3,4,3,2,1};
    int k = 0;
    while(true) {
        std::cout<< limit[k];
        k = (k+1)%8;
        // some break condition
    }
    return 0;
}
SridharKritha
  • 8,481
  • 2
  • 52
  • 43
  • 1
    You fist expound on how to do it, then you ask how to do it? Please change your question and say what your problem is... – Deduplicator Jul 08 '14 at 13:27
  • Take a look at [the triangle wave function](http://mathworld.wolfram.com/TriangleWave.html), then adjust and simplify (if possible) for your situation – Alan Jul 08 '14 at 13:43

2 Answers2

3

You can use the absolute value function like this:

int i = range;
int a = range;
while(true) {
// 0 1 2 3 4 3 2 1 0 .......... (Forward and Reverse in the range 0 - 4)
    a = abs(i-range);
    std::cout<< a; 
    i = (i+1)%(range*2); // Modulo
}

Basically, you double the range, subtract half the range (so it goes from -range to +range), then take absolute value.

EDIT: fixed code to start from zero instead of range.

SridharKritha
  • 8,481
  • 2
  • 52
  • 43
Chris Bogart
  • 472
  • 2
  • 8
1

I figured out another solution, although it's without any tricks. This is how I would have done your problem, without the absolute function:

range = 7; //can be whatever

reverse = false;

for(i = 0; i < 1000; i++){
  if(i%range != 0){
    if(!reverse){
      std::cout<< i % range;
    }else{
      std::cout<< range - (i % range);
    }
  }
  else{
    if((i/range)%2 == 1){
      reverse = true;
      std::cout<< range;
    }else{
      std::cout<< i % range;
      reverse = false;
    }
  }
}

This will provide you with the output 01234567654321012345676543210 ...

Took me a while to do this, and I know it's not really what you wanted, but just thought I'd share.

Cheers.

Edit: Although absolute is easier, sometimes it's better to write your own code, as you can modify the amount of conditions. I doubt my code is more efficient, but you never know!

Edit2: Forgot to change reverse to true.

Millar248
  • 403
  • 8
  • 18
  • I appreciate your effect. Code has some bugs... below is the output I got for your code - 0123456765432106543217654.....check 7 and 0 missing sometime. Thanks. – SridharKritha Jul 08 '14 at 14:26