math

Constraining a number to a looping range. Is there a more elegant function?


Take this function

func f(x,y) => x % y

Given the following inputs, here are the corresponding outputs.

However, I want this output

Or to put it another way, I want the output to be sort-of centred around y / 2

I can achieve this with a few if statements so the function becomes...

f(x, y) => {
  var res = x % y;
  if (res === 0) return res;
  if (res === y / 2) return res;
  if (res > y / 2) return res - y / 2;
  if (res < y / 2) return res * -1;
}

But it feels like I'm brute forcing something that might have a more elegant solution. I'm terrible at mathematics and I don't have the vocabulary to even know what to look for.

So that's the question. Is there a more elegant solution for this function?


Solution

  • It seems that desired output of function is (chart was made with WolframAlpha):

    enter image description here

    If so, a one-liner could be

    (x, y) => y/2 - ((x + y/2) % y)
    

    but might want to consider more readable

    (x, y) => {
        var modulo = x % y;
        if(modulo < y/2)
            return -modulo; 
        else
            return y - modulo;
    }