Designing function f(f(n)) == -n

前端 未结 30 2811
清酒与你
清酒与你 2020-12-02 03:32

A question I got on my last interview:

Design a function f, such that:

f(f(n)) == -n

Where n<

相关标签:
30条回答
  • 2020-12-02 03:55

    x86 asm (AT&T style):

    ; input %edi
    ; output %eax
    ; clobbered regs: %ecx, %edx
    f:
        testl   %edi, %edi
        je  .zero
    
        movl    %edi, %eax
        movl    $1, %ecx
        movl    %edi, %edx
        andl    $1, %eax
        addl    %eax, %eax
        subl    %eax, %ecx
        xorl    %eax, %eax
        testl   %edi, %edi
        setg    %al
        shrl    $31, %edx
        subl    %edx, %eax
        imull   %ecx, %eax
        subl    %eax, %edi
        movl    %edi, %eax
        imull   %ecx, %eax
    .zero:
        xorl    %eax, %eax
        ret
    

    Code checked, all possible 32bit integers passed, error with -2147483647 (underflow).

    0 讨论(0)
  • 2020-12-02 03:55

    This Perl solution works for integers, floats, and strings.

    sub f {
        my $n = shift;
        return ref($n) ? -$$n : \$n;
    }
    

    Try some test data.

    print $_, ' ', f(f($_)), "\n" for -2, 0, 1, 1.1, -3.3, 'foo' '-bar';
    

    Output:

    -2 2
    0 0
    1 -1
    1.1 -1.1
    -3.3 3.3
    foo -foo
    -bar +bar
    
    0 讨论(0)
  • 2020-12-02 03:56

    Works except int.MaxValue and int.MinValue

        public static int f(int x)
        {
    
            if (x == 0) return 0;
    
            if ((x % 2) != 0)
                return x * -1 + (-1 *x) / (Math.Abs(x));
            else
                return x - x / (Math.Abs(x));
        }
    

    pictorial

    0 讨论(0)
  • 2020-12-02 03:56

    Essentially the function has to divide the available range into cycles of size 4, with -n at the opposite end of n's cycle. However, 0 must be part of a cycle of size 1, because otherwise 0->x->0->x != -x. Because of 0 being alone, there must be 3 other values in our range (whose size is a multiple of 4) not in a proper cycle with 4 elements.

    I chose these extra weird values to be MIN_INT, MAX_INT, and MIN_INT+1. Furthermore, MIN_INT+1 will map to MAX_INT correctly, but get stuck there and not map back. I think this is the best compromise, because it has the nice property of only the extreme values not working correctly. Also, it means it would work for all BigInts.

    int f(int n):
        if n == 0 or n == MIN_INT or n == MAX_INT: return n
        return ((Math.abs(n) mod 2) * 2 - 1) * n + Math.sign(n)
    
    0 讨论(0)
  • 2020-12-02 03:57

    Uses globals...but so?

    bool done = false
    f(int n)
    {
      int out = n;
      if(!done)
      {  
          out = n * -1;
          done = true;
       }
       return out;
    }
    
    0 讨论(0)
  • 2020-12-02 03:58

    Nobody said it had to be stateless.

    int32 f(int32 x) {
        static bool idempotent = false;
        if (!idempotent) {
            idempotent = true;
            return -x;
        } else {
            return x;
        }
    }
    

    Cheating, but not as much as a lot of the examples. Even more evil would be to peek up the stack to see if your caller's address is &f, but this is going to be more portable (although not thread safe... the thread-safe version would use TLS). Even more evil:

    int32 f (int32 x) {
        static int32 answer = -x;
        return answer;
    }
    

    Of course, neither of these works too well for the case of MIN_INT32, but there is precious little you can do about that unless you are allowed to return a wider type.

    0 讨论(0)
提交回复
热议问题