Define a function f such that f(f(n)) = -n for all non-zero integers n

Python: 61 34 30 29 27 points

f: Q -> Q

in math:

       | 0.5-x   if x is in Q \ Z
f(x) = |
       | x+0.5   if x is in Z

in Python:

f=lambda x:.5+[x,-x][x%1>0]

tested with

filter(lambda n: n[0] != -n[1], map(lambda n:(n,f(f(n))),range(0,50)))

logic behind this:

When you take an integer n and put it into f you will get x+0.5. This is not an integer any more, so the next application will be 0.5-(x+0.5) which is -x.

Credits

Thanks to

  • Bakuriu for striping it down from 61 characters to 34 characters.
  • Volatility for further reducing code size to 30 characters.
  • copy for reducing code size to 29 characters (and fixing a potential floating point problem).
  • aditsu for mentioning an inconsistency that came with the changes above.

Notes

First I thought this would be ok

f = lambda n: 1j*n

but its f:N->C and that is not allowed :-/


J, 9 points (10 chars)

Based on stackoverflow answer:

   (*-[*_1&^)

First idea (13 chars):

   ((-*)-2&|*+:)

   ((-*)-2&|*+:) _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6 7 8 9 10
_9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9

   ((-*)-2&|*+:) _9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9
10 9 8 7 6 5 4 3 2 1 0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _10

C, 41 points (41 or 45 chars)

Works using both 32- and 64-bit.

f : Z -> Z (except INT_MAX):

f(n){return (abs(n)%2*2-1)*n+n?(-n<n)*2-1:0;}

If we don't have to include 0 we can shave off some chars (41 chars):

f : Z -> Z (except 0 & INT_MAX):

f(n){return (abs(n)%2*2-1)*n+(-n<n)*2-1;}

This function works by dividing all integers into 4 groups based on their sign and parity.

So we have the 4 different combinations:

+ even, + odd, - even, - odd

As we need to switch the sign of the number, but not the parity after two passes, we get two different possible sequences:

  + even -> - odd -> - even -> + odd -\
^-------------------------------------/

  + even -> + odd -> - even -> - odd -\
^-------------------------------------/

In this example I have chosen the first one.

First we need to map all even positive integers to odd negative integers. We do this by changing the sign and incrementing the number (you could also choose to decrement the number instead):

f1(n) = -n + 1

We then need to map all odd negative integers to even negative integers. We need to make sure that f2(f1(n)) = -n:

f2(f1(n)) = -n
f2(-n + 1) = -n
f2(-n) = -n - 1
f2(n) = n - 1

Using the same methods we find f3 and f4:

f3(n) = -n - 1
f4(n) =  n + 1

To combine these functions into one single function, we observe that every time n is even we switch the sign of n and every time n is positive we increment by one and otherwise we decrement by one:

f1(n) = -n + 1 (+ even)
f2(n) =  n - 1 (- odd)
f2(n) = -n - 1 (- even)
f4(n) =  n + 1 (+ odd)

This can thus be rewritten as:

f(n) = odd(n) * n + sign(n)

where odd(n) returns 1 for odd numbers and -1 for even numbers.

There are 4 solutions total:

f(n) = odd(n) * n + sign(n)  (edge cases: f(f(0))  -> -2, f(f(INT_MAX))   -> -8)
f(n) = even(n) * n - sign(n) (edge cases: f(f(0))  -> -2, f(f(INT_MIN+1)) -> -6)
f(n) = odd(n) * n - sign(n)  (edge cases: f(f(1))  -> -3, f(f(INT_MIN))   -> -5)
f(n) = even(n) * n + sign(n) (edge cases: f(f(-1)) -> -1, f(f(INT_MIN))   -> -5)

INT_MIN might always be considered an edge case in all 4 functions as -INT_MIN == INT_MIN => f(f(INT_MIN)) = INT_MIN.