How to create cyclic range of numbers C++

670 Views Asked by At

I want a range of numbers (lets say 30-50) to be cyclic. So if you do 50 + 1 = 30, OR 49 + 3 = 31. How would I do this in C++? I believe I would do it with the % operator but I'm having trouble wrapping my head around it.

4

There are 4 best solutions below

0
On

You can simply use % operator. For instance, to calculate (49 + 3), you can rewrite it as: (30 + (22 % 20)). This will result to 32. What we are doing here is, simply take the whole value greater than 30 and then modulo it by 20, so that we get a number in the range 30 - 50 because when you use modulo 20 on a number, you will get a value of range 0 - 19.

0
On

You would be working in the ring Z/21Z. Just do the addition normally, then to map any number back into the "canonical" range, you would do something like:

// Maps `n` in ring Z/(stop-start+1)Z to the equivalent
// number between start and stop (inclusive)
template<typename T>
constexpr T to_ring(T n, T start, T stop) noexcept {
    T ring_size = stop - start + 1;

    n = n % ring_size;
    if (n < 0) n = (n + ring_size) % ring_size;
    // Now 0 <= n && n < ring_size

    // offset === 0 in this ring (offset % ring_size == 0),
    // so adding it will give an equivalent number
    T offset = start - (start % ring_size);
    n += offset;

    // ring_size === 0, so still equivalent, in case this number is outside the range
    // Only one of the following can be true, depending on the sign of `start`
    if (n < start) n += ring_size;
    if (n > stop) n -= ring_size;

    assert(start <= n && n <= stop);
    return n;
}

And then your addition would look like:

// 50 + 1 = 51 = 30
std::cout << "50 + 1 = " << to_ring(50 + 1, 30, 50) << '\n';
// 101 + 57 = 158 = 32
//          = 38 + 36 = 74 = 32
std::cout << "101 + 57 = " << to_ring(101 + 57, 30, 50) << '\n';
std::cout << to_ring(101, 30, 50) << " + " << to_ring(57, 30, 50) << " = "
          << to_ring(to_ring(101, 30, 50) + to_ring(57, 30, 50), 30, 50) << '\n';

Note it does not matter that you map the numbers before you add them, the result will be the same (since after mapping, they are equivalent numbers in the ring)

0
On

Here is my take on this. If you want a recursive function that does it for you, you can write it out in multiple steps like this:

#include <iostream>

int next_cyclical_number(int x, int min, int max){
    if( min >= max )
        return -99999;
    if( x < min )
        x = min;

    int mod_value = max - min;

    int offset = min;

    int temp = x - min;

    int remainder = (temp + 1)%mod_value;

    int ret_val = min + remainder;

    return ret_val;
}

int main(int argc, char *argv[])
{
    // show 100 numbers using the function

    int current_number = 0;
    for(int i = 0; i < 100; i++){
        current_number = next_cyclical_number(current_number, 30, 51);
        std::cout << "i: " << i << "\t" << "number: " << current_number << std::endl;
    }

    return 0;
}

Output:

i: 0    number: 31
i: 1    number: 32
i: 2    number: 33
i: 3    number: 34
i: 4    number: 35
i: 5    number: 36
i: 6    number: 37
i: 7    number: 38
i: 8    number: 39
i: 9    number: 40
i: 10   number: 41
i: 11   number: 42
i: 12   number: 43
i: 13   number: 44
i: 14   number: 45
i: 15   number: 46
i: 16   number: 47
i: 17   number: 48
i: 18   number: 49
i: 19   number: 50
i: 20   number: 30
i: 21   number: 31
i: 22   number: 32
i: 23   number: 33
i: 24   number: 34
i: 25   number: 35
i: 26   number: 36
i: 27   number: 37
i: 28   number: 38
i: 29   number: 39
i: 30   number: 40
i: 31   number: 41
i: 32   number: 42
i: 33   number: 43
i: 34   number: 44
i: 35   number: 45
i: 36   number: 46
i: 37   number: 47
i: 38   number: 48
i: 39   number: 49
i: 40   number: 50
i: 41   number: 30
i: 42   number: 31
i: 43   number: 32
i: 44   number: 33
i: 45   number: 34
i: 46   number: 35
i: 47   number: 36
i: 48   number: 37
i: 49   number: 38
i: 50   number: 39
i: 51   number: 40
i: 52   number: 41
i: 53   number: 42
i: 54   number: 43
i: 55   number: 44
i: 56   number: 45
i: 57   number: 46
i: 58   number: 47
i: 59   number: 48
i: 60   number: 49
i: 61   number: 50
i: 62   number: 30
i: 63   number: 31
i: 64   number: 32
i: 65   number: 33
i: 66   number: 34
i: 67   number: 35
i: 68   number: 36
i: 69   number: 37
i: 70   number: 38
i: 71   number: 39
i: 72   number: 40
i: 73   number: 41
i: 74   number: 42
i: 75   number: 43
i: 76   number: 44
i: 77   number: 45
i: 78   number: 46
i: 79   number: 47
i: 80   number: 48
i: 81   number: 49
i: 82   number: 50
i: 83   number: 30
i: 84   number: 31
i: 85   number: 32
i: 86   number: 33
i: 87   number: 34
i: 88   number: 35
i: 89   number: 36
i: 90   number: 37
i: 91   number: 38
i: 92   number: 39
i: 93   number: 40
i: 94   number: 41
i: 95   number: 42
i: 96   number: 43
i: 97   number: 44
i: 98   number: 45
i: 99   number: 46
1
On

Before performing your addition or subtraction, you need to subtract 30, then perform your operation, after that divide modulo 20 (because 50-30=20) and finally add-up 30 to get your desired result.