How can I modulo when my numbers start from 1, not zero?
Your next = (i + m) % n
isn't right anyway - it'll return zero in some cases.
Try this instead:
next(i, m) = ((i - 1) + m) % n + 1
prev(i, m) = ((i - 1) + n - m) % n + 1
In effect, take one off, then find the correct value, and then add the one back on again.
For prev
, add n
first to ensure that you never take the modulo of a negative number
Just subtract 1 and add 1 afterwards.
In most programming languages, you need to watch out when finding a "previous" value, because for negative numbers, modulo does not work as you want in this case: it returns a negative number.
Here's the C/C++ version:
int next(int i, int m, int n) { return (i + m - 1) % n + 1; }
int prev(int i, int m, int n) { return (i - m + n - 1) % n + 1; }
However, in Perl modulo always returns a positive value (at least when the second operand is a positive integer). Basically it does what you want. So you can write the following and leave out the + $_[2]
:
sub nxt { ($_[0] + $_[1] - 1) % $_[2] + 1; }
sub prv { ($_[0] - $_[1] - 1) % $_[2] + 1; }