[Question]
  [
Consider a regular grid, where each cell has integer coordinates. We can group the cells into (square-shaped) "rings" where the cells in each ring have the same [Chebyshev distance](https://en.wikipedia.org/wiki/Chebyshev_distance) (or chessboard distance) from the origin. Your task is to take such a cell coordinate and rotate that cell by one position counter-clockwise within its ring. This implements the following mapping:
[![enter image description here](https://i.stack.imgur.com/skFsp.png)](https://i.stack.imgur.com/skFsp.png)
So for example if the input is `(3, -2)` you should output `(3, -1)`. Note that `(0, 0)` is the only input that should map to itself.
## Rules
The I/O format is fairly flexible. You can use two individual numbers, a pair/list/array/tuple of numbers, a single complex number, a string containing two numbers, etc.
You may assume that `-128 < x,y < 128`.
You may write a [program or a function](https://codegolf.meta.stackexchange.com/q/2419) and use any of the our [standard methods](https://codegolf.meta.stackexchange.com/q/2447) of receiving input and providing output.
You may use any [programming language](https://codegolf.meta.stackexchange.com/q/2028), but note that [these loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are forbidden by default.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest valid answer – measured in *bytes* – wins.
## Test Cases
```
(0, 0)       => (0, 0)
(1, 0)       => (1, 1)
(1, 1)       => (0, 1)
(0, 1)       => (-1, 1)
(-1, 1)      => (-1, 0)
(-1, 0)      => (-1, -1)
(-1, -1)     => (0, -1)
(0, -1)      => (1, -1)
(1, -1)      => (1, 0)
(95, -12)    => (95, -11)
(127, 127)   => (126, 127)
(-2, 101)    => (-3, 101)
(-65, 65)    => (-65, 64)
(-127, 42)   => (-127, 41)
(-9, -9)     => (-8, -9)
(126, -127)  => (127, -127)
(105, -105)  => (105, -104)
```
  
[Answer]
## JavaScript (ES6), ~~60~~ 59 bytes
Takes input with currying syntax `(x)(y)` and returns an array `[new_x, new_y]`.
```
x=>y=>(x|y&&((z=x+(y<0))>-y?z>y?y++:x--:z>y?x++:y--),[x,y])
```
### How it works
Our main task is to determine in which quadrant we are, so that we know in which direction to move.
We can use this formula as a first approximation:
```
x > -y ? (x > y ? 0 : 1) : (x > y ? 2 : 3)
```
Here is what we get:
```
3 1 1 1 1 1 1 1 1
3 3 1 1 1 1 1 1 0
3 3 3 1 1 1 1 0 0
3 3 3 3 1 1 0 0 0
3 3 3 3 3 0 0 0 0
3 3 3 3 2 2 0 0 0
3 3 3 2 2 2 2 0 0
3 3 2 2 2 2 2 2 0
3 2 2 2 2 2 2 2 2
```
Almost there. But the bottom left and bottom right corners of the rings are invalid. We need to shift the lower half of the matrix by one position to the left, so we define `z` as:
```
z = y < 0 ? x + 1 : x
```
And we replace `x` with `z` in our formula:
```
z > -y ? (z > y ? 0 : 1) : (z > y ? 2 : 3)
```
Which leads to:
```
3 1 1 1 1 1 1 1 1 
3 3 1 1 1 1 1 1 0 
3 3 3 1 1 1 1 0 0 
3 3 3 3 1 1 0 0 0 
3 3 3 3 3 0 0 0 0 
3 3 3 2 2 0 0 0 0 
3 3 2 2 2 2 0 0 0 
3 2 2 2 2 2 2 0 0 
2 2 2 2 2 2 2 2 0 
```
The whole matrix is now correct, except for the special case `[0, 0]` (no move at all) which must be addressed separately.
### Test cases
```
let f =
x=>y=>(x|y&&((z=x+(y<0))>-y?z>y?y++:x--:z>y?x++:y--),[x,y])
console.log(f(0)(0));       // => (0, 0)
console.log(f(1)(0));       // => (1, 1)
console.log(f(1)(1));       // => (0, 1)
console.log(f(0)(1));       // => (-1, 1)
console.log(f(-1)(1));      // => (-1, 0)
console.log(f(-1)(0));      // => (-1, -1)
console.log(f(-1)(-1));     // => (0, -1)
console.log(f(0)(-1));      // => (1, -1)
console.log(f(1)(-1));      // => (1, 0)
console.log(f(95)(-12));    // => (95, -11)
console.log(f(127)(127));   // => (126, 127)
console.log(f(-2)(101));    // => (-3, 101)
console.log(f(-65)(65));    // => (-65, 64)
console.log(f(-127)(42));   // => (-127, 41)
console.log(f(-9)(-9));     // => (-8, -9)
console.log(f(126)(-127));  // => (127, -127)
console.log(f(105)(-105));  // => (105, -104)
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~20~~ ~~14~~ 12 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
S;IṠN0n/¦Ạ¡+
```
Input and output are in form of arrays. [Try it online!](http://jelly.tryitonline.net/#code=UztJ4bmgTjBuL8Km4bqgwqEr&input=&args=Wzk1LCAtMTJd) or [verify all test cases](http://jelly.tryitonline.net/#code=UztJ4bmgTjBuL8Km4bqgwqErCsOH4oKsRw&input=&args=WzAsIDBdLCBbMSwgMF0sIFsxLCAxXSwgWzAsIDFdLCBbLTEsIDFdLCBbLTEsIDBdLCBbLTEsIC0xXSwgWzAsIC0xXSwgWzEsIC0xXSwgWzk1LCAtMTJdLCBbMTI3LCAxMjddLCBbLTIsIDEwMV0sIFstNjUsIDY1XSwgWy0xMjcsIDQyXSwgWy05LCAtOV0sIFsxMjYsIC0xMjddLCBbMTA1LCAtMTA1XQ).
### Background
To figure out in which direction we have to move, we can observe the relative position of the start point to the quadrant bisectors **x + y = 0** (blue) and **x - y = 0** (red).
![diagram](https://i.stack.imgur.com/n9THn.png)
* The origin is fixed. We advance by adding **[0, 0]** to the start point.
* Points in the topmost triangle – including the bisector of the first quadrant – have positive sum and non-negative delta (**y - x**). We advance by adding **[-1, 0]** to the start point.
* Points in the leftmost triangle – including the bisector of the second quadrant – have non-positive sum and positive delta. We advance by adding **[0, -1]** to the start point.
* Points in the bottommost triangle – including the bisector of the third quadrant – have negative sum and non-positive delta. We advance by adding **[1, 0]** to the start point.
* Points in the rightmost triangle – including the bisector of the fourth quadrant – have non-negative sum and negative delta. We advance by adding **[0, 1]** to the start point.
To figure out the correct direction, we compute **[-sign(x + y), -sign(y - x)]**, which has only nine possible outcomes.
The following table illustrates which outcomes have to get mapped to which directions.
```
    sign(x+y) |  sign(y-x) | -sign(x+y) | -sign(y-x) |     Δx     |     Δy
  ------------+------------+------------+------------+------------+------------
        0     |      0     |      0     |      0     |      0     |      0
        1     |      0     |     -1     |      0     |     -1     |      0
        1     |      1     |     -1     |     -1     |     -1     |      0
        0     |      1     |      0     |     -1     |      0     |     -1
       -1     |      1     |      1     |     -1     |      0     |     -1
       -1     |      0     |      1     |      0     |      1     |      0
       -1     |     -1     |      1     |      1     |      1     |      0
        0     |     -1     |      0     |      1     |      0     |      1
        1     |     -1     |     -1     |      1     |      0     |      1
```
This leaves three cases.
* If at least one of the signs is **0**, **[Δx, Δy] = [-sign(x+y), -sign(y-x)]**.
* If the signs are equal and non-zero, **[Δx, Δy] = [-sign(x+y), 0]**.
* If the signs are different and non-zero, **[Δx, Δy] = [0, -sign(y-x)]**.
### How it works
```
S;IṠN0n/¦Ạ¡+  Main link. Argument: [x, y] (pair of integers)
S             Sum; compute x + y.
  I           Increments; compute [y - x].
 ;            Concatenate; yield [x + y, y - x].
   Ṡ          Sign; compute [sign(x + y), sign(y - x)].
    N         Negate; yield [-sign(x + y), -sign(y - x)].
          ¡   Do n times:
         Ạ      Set n to all([-sign(x + y), -sign(y - x)]), i.e., 1 if the signs
                are both non-zero and 0 otherwise.
        ¦       Conditional application:
      n/          Yield 1 if the signs are not equal, 0 if they are.
     0            Replace the coordinate at 1 or 0 with a 0.
              This returns [Δx, Δy].
           +  Add; yield  [Δx + x, Δy + y].
```
[Answer]
# [Pyth](http://github.com/isaacg1/pyth), 19 bytes
```
&Q+^.jZ1.RhycPQ.n0Z
```
[Try it online!](http://pyth.tryitonline.net/#code=JlErXi5qWjEuUmh5Y1BRLm4wWg&input=LTktOWo)
Translation of my [Julia answer](https://codegolf.stackexchange.com/a/96436/3852):
```
&Q                    If input is 0, then 0, else:
             PQ         Get phase of input
            c  .n0      Divide by π
           y            Double
          h             Add one
        .R        Z     Round to integer
   ^.jZ1                Raise i to this power
  +                     Add to input
```
[Answer]
## Python, 55 bytes
```
lambda x,y:(x-(-y<x<=y)+(y<=x<-y),y+(~x<y<x)-(x<y<=-x))
```
Detects the four diagonal quadrants, and shifts the appropriate coordinate.
[Answer]
# Haskell, ~~77~~ ~~71~~ 69 bytes
```
x#y|y>=x,-x<y=(x-1,y)|y>x=(x,y-1)|y< -x=(x+1,y)|y<x=(x,y+1)|1>0=(0,0)
```
This is just checking each of those tilted quadrants, and modifying the input accordingly. Note that the spaces are necessary, otherwise e.g. `>-` would be understood as an operator (which is not defined).
Thank you @nimi for removing a few more bytes!
[Answer]
# Ruby, 68
Lambda function takes complex number as argument, returns complex number.
```
->z{k=1
4.times{z*=?i.to_c
x,y=z.rect
y*y>=x*x&&y<-x&&(z+=k;k=0)}
z} 
```
We rotate the point through 90 degrees 4 times by multiplying by `i`. It therefore passes through all 4 quadrants, and would be returned unchanged - except for the fact we modify it when it is in a specific one of them. The fact it is always modified in the same quadrant simplifies the modification.
It is easiest to follow if we alter it `z` when it is in the righthand quadrant. in this case we need to increase the y coordinate by 1 (i.e add `i` to `z`.)
We check `x.abs>=y.abs` by comparing the squares of `x` and `y`. This tells us the point is in the righthand or lefthand quadrant, not top or bottom. To check it is in fact in the righthand quadrant we further check that `x>y` (strictly greater because we want to exclude the case `x=y` which belongs to the "top" quadrant.) Where this is true we add `i` to `z`.
For golfing reasons, adding `i` is not desirable. Instead we modifiy the number when it is in the bottom quadrant, in which case we have to add 1 to the `x` coordinate (add 1 to `z`.) In this case we test that `y*y>=x*x` to check it is in the top or bottom quadrant. To further ensure it is in the bottom quadrant we need to check `y<-x` (strictly excluding the case of the bottom right corner where `y=-x`.)
An advantage of this check is there is no special case for the coordinate 0,0. Unfortunately it was found that moving the point can shift it to a different quadrant and this means that a second movement must be suppressed should that quadrant be checked again, which probably negates the advantage.
**Example 1**
```
Input                                        95,-12
Rotate 90deg                                 12,95    
Rotate 90deg                                -95,12    
Rotate 90deg                                -12,-95 
Rotate 90deg                                 95,-12
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x     95,-11
The check and alteration of the coordinate is done AFTER the rotation.
Thus in this case it gets done in the 4th iteration of the loop, not the 1st.
If the code were rewritten to do the check and alteration BEFORE the rotation, 
it would be done in the 1st iteration instead of the 4th.
```
**Example 2**
```
Input                                        -1,0
Rotate 90deg                                  0,-1
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x      1,-1
Rotate 90deg                                  1,1
Rotate 90deg                                  1,-1
Rotate 90deg                                 -1,-1
y.abs>=x.abs?=TRUE, y<-x=TRUE but DO NOT CHANGE x!
This is an unusual situation due to the fact that the first move caused the
point to advance by one quadrant. We do NOT want to move it again, for this
reason we need to set k to 0 the first time it is moved.
```
**In test program**
```
f=->z{k=1                   #amount to be added to coordinate
4.times{z*=?i.to_c          #iterate 4 times, rotating point by 90deg till it reaches the original orientation
x,y=z.rect                  #separate out x and y for testing
y*y>=x*x&&y<-x&&(z+=k;k=0)} #if y.abs>=x.abs and y negative and not equal -x, move the point and zero k.
z}                          #return z
puts f[Complex(0, 0)]       # (0, 0)
puts f[Complex(1, 0)]       # (1, 1)
puts f[Complex(1, 1)]       # (0, 1)
puts f[Complex(0, 1)]       # (-1, 1)
puts f[Complex(-1, 1)]      # (-1, 0)
puts
puts f[Complex(-1, 0)]      # (-1, -1)
puts f[Complex(-1, -1)]     # (0, -1)
puts f[Complex(0, -1)]      # (1, -1)
puts f[Complex(1, -1)]      # (1, 0)
puts f[Complex(95, -12)]    # (95, -11)
puts f[Complex(127, 127)]   # (126, 127)
puts
puts f[Complex(-2, 101)]    # (-3, 101)
puts f[Complex(-65, 65)]    # (-65, 64)
puts f[Complex(-127, 42)]   # (-127, 41)
puts f[Complex(-9, -9)]     # (-8, -9)
puts f[Complex(126, -127)]  # (127, -127)
puts f[Complex(105, -105)]  # (105, -104)
```
**Diagram**
The following image shows (blue) the area where `x*x>=y*y`, (yellow) the area where `y<-x` and (green) the intersection of these, which is the region where the correct transformation is the addition of 1 to `z`.
[![enter image description here](https://i.stack.imgur.com/ypl8b.png)](https://i.stack.imgur.com/ypl8b.png)
[Answer]
## Python, 52 bytes
```
h=lambda z:z and 1j*h(z/1j)if'-'in`z*1j-z-1`else z+1
```
Complex input and output. To test the point for being in the lower diagonal quadrant, first rotate it 135 counterclockwise to move that quadrant to the (x>0, y>0) standard quadrant, and test if the result has no minus symbol in the string representation. Subtracting 1 first takes care of the boundary condition.
If it's not in that quadrant, rotate the whole problem 90 degrees. The input is zero is specially handled to output itself.
Other attempts with complex numbers:
```
## 56 bytes
## Coordinate input, complex output
q=lambda x,y:(y<=x<-y)*(1j*y-~x)or x+1j*y and 1j*q(y,-x)
## 60 bytes
h=lambda z:(z+1)*(z.imag<=z.real<-z.imag)or z and 1j*h(z/1j)
## 63 bytes
from cmath import*
h=lambda z:z and 1j**(phase(z*1j-z)*2//pi)+z
```
[Answer]
## Mathematica, 34 bytes
```
±0=0
±z_:=z+I^Floor[2Arg@z/Pi+3/2]
```
This defines a unary operator `±` which takes and returns a complex number whose components represent `x` and `y`.
Now that Lynn has revealed the complex number solution and Dennis has beaten my score, I don't feel so bad for posting my golfed referenced implementation. :) (It turns out to be virtually identical to Lynn's answer.)
[Answer]
# [MATL](http://github.com/lmendo/MATL), ~~19~~ 17 bytes
```
t|?JGJq*X/EYP/k^+
```
This uses complex numbers as input and output.
[Try it online!](http://matl.tryitonline.net/#code=dHw_SkdKcSpYL0VZUC9rXis&input=LTEyNys0Mmo) Or [verify all test cases](http://matl.tryitonline.net/#code=IkAKdHw_SkBKcSpYL0VZUC9rXisKXVZAVicgLT4gJ2JoaEQ&input=WzArMGogMSswaiAxKzFqIDArMWogLTErMWogLTErMGogLTEtMWogMS0xaiA5NS0xMmogMTI3KzEyN2ogLTIrMTAxaiAtNjUrNjVqIC0xMjcrNDJqIC05LTlqIDEyNi0xMjdqIDEwNS0xMDVqXQ).
### Explanation
Let's take input `-127+42j` as an example.
```
t|       % Implicit input. Duplicate and take absolute value
         % STACK: -127+42j, 133.764718816286
?        % If nonzero
         % STACK: -127+42j
  J      %   Push j (imaginary unit)
         %   STACK: -127+42j, j
  GJq*   %   Push input multiplied by -1+j. This adds 3*pi/4 to the phase of the input
         %   STACK: -127+42j, j, 85-169i
  X/     %   Phase of complex number
         %   STACK: -127+42j, j, -1.10478465600433
  EYP/   %   Divide by pi/2
         %   STACK: -127+42j, j, -0.703327756220671
  k      %   Round towards minus infinity
         %   STACK: -127+42j, j, -1
  ^      %   Power
         %   STACK: -127+42j, -j
  +      %   Add
         %   STACK: -127+41j
         % Implicit end
         % Implicit display
        
```
[Answer]
# Ruby, 51 bytes
**Original form**
```
->x,y{d=x*x-y*y
[x+(d>0?0:-y<=>x),y+(d<0?0:x<=>y)]}
```
**Alternate form per Xnor's comment**
```
->x,y{[x+(x*x>y*y ?0:-y<=>x),y+(x*x<y*y ?0:x<=>y)]}
```
Uses the same type of inequalities as my other answer, but in a different way.
**In test program**
```
f=->x,y{d=x*x-y*y
[x+(d>0?0:-y<=>x), #if y.abs>=x.abs: x+=1 if -y>x, x-=1 if -y<x 
y+(d<0?0:x<=>y)]}  #if x.abs>=y.abs: y+=1 if  x>y, y-=1 if  x<y
p f[0, 0]       # (0, 0)
p f[1, 0]       # (1, 1)
p f[1, 1]       # (0, 1)
p f[0, 1]       # (-1, 1)
p f[-1, 1]      # (-1, 0)
puts
p f[-1, 0]      # (-1, -1)
p f[-1, -1]     # (0, -1)
p f[0, -1]      # (1, -1)
p f[1, -1]      # (1, 0)
p f[95, -12]    # (95, -11)
p f[127, 127]   # (126, 127)
puts
p f[-2, 101]    # (-3, 101)
p f[-65, 65]    # (-65, 64)
p f[-127, 42]   # (-127, 41)
p f[-9, -9]     # (-8, -9)
p f[126, -12]   # (127, -127)
p f[105, -105]  # (105, -104)
```
[Answer]
# Julia, ~~38~~ 34 bytes
```
!z=z==0?0:z+im^int(2angle(z)/pi+1)
```
Dennis saved four bytes. Thanks!
[Try it online!](http://julia.tryitonline.net/#code=IXo9ej09MD8wOnoraW1eaW50KDJhbmdsZSh6KS9waSsxKQoKcHJpbnRsbighKDAraW0qIDApICAgICApCnByaW50bG4oISgxK2ltKiAwKSAgICAgKQpwcmludGxuKCEoMStpbSogMSkgICAgICkKcHJpbnRsbighKDAraW0qIDEpICAgICApCnByaW50bG4oISgtMStpbSogMSkgICAgKQpwcmludGxuKCEoLTEraW0qIDApICAgICkKcHJpbnRsbighKC0xK2ltKiAtMSkgICApCnByaW50bG4oISgwK2ltKiAtMSkgICAgKQpwcmludGxuKCEoMStpbSogLTEpICAgICkKcHJpbnRsbighKDk1K2ltKiAtMTIpICApCnByaW50bG4oISgxMjcraW0qIDEyNykgKQpwcmludGxuKCEoLTIraW0qIDEwMSkgICkKcHJpbnRsbighKC02NStpbSogNjUpICApCnByaW50bG4oISgtMTI3K2ltKiA0MikgKQpwcmludGxuKCEoLTkraW0qIC05KSAgICkKcHJpbnRsbighKDEyNitpbSogLTEyNykpCnByaW50bG4oISgxMDUraW0qIC0xMDUpKQo&input=)
[Answer]
# C++, 94 bytes
```
#define a(x) (x>0?x:-(x))
#define f(x,y) y>a(x-.5)?x--:-y>a(x+.5)?x++:x>a(y+.5)?y++:x|y?y--:x;
```
Ungolfed:
```
#define a(x) (x>0?x:-(x))  //shorter than std::abs from <cmath>
#define f(x,y) 
    y>a(x-.5)?      // shift absolute value function by 0.5 to the right to get upper fourth
        x--:
        -y>a(x+.5)? //same for lower fourth
            x++:
            x>a(y+.5)? //same for right fourth
                y++:
                x|y? //only left fourth and 0 are left
                    y--:
                    x; //can't be empty, just does nothing
```
Usage:
```
#include <iostream>
void test(int x, int y, int rx, int ry){
    std::cout << "(" << x << ", " << y << ")=>";
    f(x,y);
    std::cout << "(" << x << ", " << y << ") - " << ((x==rx&&y==ry)?"OK":"FAILURE") << std::endl;
}
//Using the test cases from the question
int main() {
    test(0, 0, 0, 0);
    test(1, 0, 1, 1);
    test(1, 1, 0, 1);
    test(0, 1, -1, 1);
    test(-1, 1, -1, 0);
    test(-1, 0, -1, -1);
    test(-1, -1, 0, -1);
    test(0, -1, 1, -1);
    test(1, -1, 1, 0);
    test(95, -12, 95, -11);
    test(127, 127, 126, 127);
    test(-2, 101, -3, 101);
    test(-65, 65, -65, 64);
    test(-127, 42, -127, 41);
    test(-9, -9, -8, -9);
    test(126, -127, 127, -127);
    test(105, -105, 105, -104);
    return 0;
}
```
[Try it online](http://ideone.com/XV93r8)
[Answer]
## R, 131 110 bytes
A function that takes the two integers, `x,y` as inputs and writes the output to stdout. The solution follows @Dennis' control flow scheme but could probably be golfed.
EDIT: Updated code based on @JDL's suggestions and saved a bunch of bytes.
```
function(x,y){X=sign(x+y);Y=sign(y-x);if(!X|!Y){x=x-X;y=y-Y}else if(X==Y&X&Y)x=x-X else if(X-Y&X)y=y-Y;c(x,y)}
```
**Ungolfed**
```
f=function(x,y){
    X=sign(x+y)                 # calculate sign 
    Y=sign(y-x)                 #  =||=
    if(!X|!Y){x=x-X;y=y-Y}      # if at least one is 0: subtract sign
    else if(X==Y&X&Y)x=x-X      # if signs are equal and non-zero: add sign to x
    else if(X-Y&X)y=y-Y         # if signs are not equal and non-zero: add sign to y
    c(x,y)                      # print to stdout
}
```
[Answer]
# JavaScript (ES6), 57 bytes (55–63†)
Accepts an [x, y] array, modifies it in-place, and returns it.
```
c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y),c)
```
## How it works
```
c=>(
```
This is a single-parameter arrow function with a `return`-free concise body.
```
[x,y]=c
```
The parameter is immediately destructured into `x` and `y` variables.
```
,
```
The comma operator combines multiple expressions into one, using the result of the last.
```
i=x>y|x==y&x<0
```
`i` is used for differentiating increment and decrement cases. When `x` is greater than `y`, we are in either the bottom or right quadrant, and need to advance in one dimension (`i=1` by boolean-to-number coercion). Likewise when we are on the negative portion of the dividing **x = y** diagonal. In all other cases—including the origin—no increment is required (`i=0`).
```
c[i^x<-y|x==-y]
```
We use a somewhat similar expression for controlling which array index to adjust. When we are incrementing and not in the left or bottom quadrants (or when we are *not* incrementing and *in* the left or bottom), then the bitwise XOR will produce `1` and we will adjust the **y** value. Likewise for when we are on the dividing **x = -y** diagonal (including the origin). In all other cases, the index will be `0` (**x**).
```
-=-i|!!(x|y)
```
When `i` is `1`, we will add it to the specified value. When `i` is `0`, we will subtract 1 from the value *if and only if* we are not at the origin. The latter is detected by `x|y` yielding nonzero, clipped to {0, 1} by boolean coercion, and the negation of `i` allows us to use bitwise OR instead of logical (since `-1` has no zero bits, it is safe from modification).
```
c
```
The array is last, so it will be returned.
## Testing
```
let f =
    c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y),c)
let cases = `
(0, 0)       => (0, 0)
(1, 0)       => (1, 1)
(1, 1)       => (0, 1)
(0, 1)       => (-1, 1)
(-1, 1)      => (-1, 0)
(-1, 0)      => (-1, -1)
(-1, -1)     => (0, -1)
(0, -1)      => (1, -1)
(1, -1)      => (1, 0)
(95, -12)    => (95, -11)
(127, 127)   => (126, 127)
(-2, 101)    => (-3, 101)
(-65, 65)    => (-65, 64)
(-127, 42)   => (-127, 41)
(-9, -9)     => (-8, -9)
(126, -127)  => (127, -127)
(105, -105)  => (105, -104)
`;
let failures = cases.trim().split("\n").filter(l => {
    const FAIL = true;
    let m = /.*?(-?\d+).*?(-?\d+).*?(-?\d+).*?(-?\d+)/.exec(l);
    if (!m) return FAIL;
    let [_, x, y, X, Y] = m;
    let [x2, y2] = f([+x, +y]);
    if (x2==X && y2==Y) return !FAIL;
    console.log("(%s) yielded (%s); expected (%s)", [x, y], [x2, y2], [X, Y]);
    return FAIL;
});
console.log("failures: " + failures.length);
// => failures: 0
```
## †Variations
We can save two more bytes by skipping a meaningful return value and using *only* the input mutation:
```
c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y))
```
…or we can skip input mutation and make all variables local for a pure function, at the cost of six bytes:
```
([x,y],i=x>y|x==y&x<0,c=[x,y])=>(c[i^x<-y|x==-y]-=-i|!!(x|y),c)
```
[Answer]
## JavaScript (ES6), ~~80~~ 76 bytes
```
(x,y,s=Math.max(x,y,-x,-y))=>(s?x+s?y-s?x-s?x++:y++:x--:y+s?y--:x++:0,[x,y])
```
[Answer]
## Haskell, 53 bytes
```
0%0=(0,0)
x%y|y>=0-x,y<x=(x,y+1)|(p,q)<-(-y)%x=(q,-p)
```
Takes two numbers, outputs a tuple. If the point is in the east section `-x<=y<x`, increase the second coordinate by 1. Otherwise, cycle the quadrants by rotating the input point 90 degrees, calling the function on it, then rotating back.
[Answer]
## Racket 191 bytes
```
(cond[(= 0 x y)(list x y)][(= x y)(if(> x 0)(list(sub1 x)y)(list(add1 x)y))][(> x y)(if(>= x(abs y))
(list x(add1 y))(list(add1 x)y))][(< x y)(if(> y(abs x))(list(sub1 x)y)(list x(sub1 y)))])
```
Ungolfed (directly translating figure directions to code without using any intermediate formula): 
```
(define(f x y)
  (cond
    [(= 0 x y) (list x y)]
    [(= x y)
     (if (> x 0)
         (list (sub1 x) y)   ; left
         (list (add1 x) y))] ; right
    [(> x y)
     (if (>= x (abs y))
         (list x (add1 y))   ; up
         (list (add1 x) y))] ; right
    [(< x y)
     (if (> y (abs x))
         (list (sub1 x) y)   ; left
         (list x (sub1 y)))] ; down
    ))
```
Testing: 
```
(f 0  0)      
(f 1  0)     
(f 1  1)     
(f 0  1)     
(f -1  1)    
(f -1  0)    
(f -1  -1)   
(f 0  -1)    
(f 1  -1)    
(f 95  -12)  
(f 127  127) 
(f -2  101)  
(f -65  65)  
(f -127  42) 
(f -9  -9)    
(f 126  -127) 
(f 105  -105) 
```
Output: 
```
'(0 0)
'(1 1)
'(0 1)
'(-1 1)
'(-1 0)
'(-1 -1)
'(0 -1)
'(1 -1)
'(1 0)
'(95 -11)
'(126 127)
'(-3 101)
'(-65 64)
'(-127 41)
'(-8 -9)
'(127 -127)
'(105 -104)
```
[Answer]
# [Actually](http://github.com/Mego/Seriously), 16 bytes
This takes a complex number as input and outputs another complex number. Golfing suggestions welcome! [Try it online!](http://actually.tryitonline.net/#code=O2DigqfilaZAL8-EdUzDr-KBvyswYOKVrFg&input=Myswag)
```
;`₧╦@/τuLïⁿ+0`╬X
```
**Ungolfing**
```
         Implicit input z.
;        Duplicate z.
`...`╬   If z is non-zero (any a+bi except 0+0j), run the following function.
           Stack: z, z
  ₧        Get phase(z).
  ╦@/      Divide phase(z) by pi.
  τuL      Push floor(2*phase(z)/pi + 1).
  ïⁿ       Push 1j ** floor(2*phase(z)/pi + 1).
  +        And add it to z. This is our rotated z.
  0        Push 0 to end the function.
X        Discard either the duplicate (0+0j) or the 0 from the end of function.
         Implicit return.
```
[Answer]
# Scala, 184 bytes
```
val s=math.signum _
(x:Int,y:Int)=>{val m=x.abs max y.abs
if(x.abs==y.abs)if(s(x)==s(y))(x-s(x),y)else(x,y-s(y))else
if(x.abs==m)(x,y+Seq(0,x).indexOf(m))else(x-Seq(0,y).indexOf(m),y)}
```
### Ungolfed:
```
import math._
(x: Int, y: Int) => {
  val max = max(x.abs, y.abs)
  if (x.abs == y.abs)
    if (signum(x) == signum(y))
      (x - signum(x), y)
    else
      (x, y - signum(y))
  else
    if (x.abs == max)
      (x, y + Seq(0, x).indexOf(max))
    else
      (x - Seq(0, y).indexOf(max), y)
}
```
### Explanation:
```
val s=math.signum _             //define s as an alias to math.signum
(x:Int,y:Int)=>{                //define an anonymous function
  val m=x.abs max y.abs           //calculate the maximum of the absolute values,
                                  //which is 1 for the innermost circle and so on.
  if(x.abs==y.abs)                //if we have a cell at a corner of a circle
    if(s(x)==s(y))                  //if it's at the top-left or bottom-right, we need to
                                    //modify the x value
      (x-s(x),y)                      //if x is positive (bottom-right),
                                      //we need to return (x+1,y),
                                      //(x-1,y) If it's at the top-left.
                                      //This can be simplified to (x-s(x),y)
    else                            //for top-right and bottom-left, 
      (x,y-s(y))                      //modify y in the same way.
  else                            //we don't have a corner piece
    if(x.abs==m)                    //if we're at the left or right edge of the square
      (x,y+Seq(0,x).indexOf(m))       //if it's a piece from the right edge, add one
                                      //to y, else subtract 1
    else                            //it's a piece from the top or bottm edge
      (x-Seq(0,y).indexOf(m),y)       //subtract 1 from x if it's from the top edge,
                                      //else subtract -1
}
```
]