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

前端 未结 30 2812
清酒与你
清酒与你 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:51

    Thanks to overloading in C++:

    double f(int var)
    {
     return double(var);
    } 
    
    int f(double var)
    {
     return -int(var);
    }
    
    int main(){
    int n(42);
    std::cout<<f(f(n));
    }
    
    0 讨论(0)
  • 2020-12-02 03:51

    For all 32-bit values (with the caveat that -0 is -2147483648)

    int rotate(int x)
    {
        static const int split = INT_MAX / 2 + 1;
        static const int negativeSplit = INT_MIN / 2 + 1;
    
        if (x == INT_MAX)
            return INT_MIN;
        if (x == INT_MIN)
            return x + 1;
    
        if (x >= split)
            return x + 1 - INT_MIN;
        if (x >= 0)
            return INT_MAX - x;
        if (x >= negativeSplit)
            return INT_MIN - x + 1;
        return split -(negativeSplit - x);
    }
    

    You basically need to pair each -x => x => -x loop with a y => -y => y loop. So I paired up opposite sides of the split.

    e.g. For 4 bit integers:

    0 => 7 => -8 => -7 => 0
    1 => 6 => -1 => -6 => 1
    2 => 5 => -2 => -5 => 2
    3 => 4 => -3 => -4 => 3
    
    0 讨论(0)
  • 2020-12-02 03:52

    Here's a proof of why such a function can't exist, for all numbers, if it doesn't use extra information(except 32bits of int):

    We must have f(0) = 0. (Proof: Suppose f(0) = x. Then f(x) = f(f(0)) = -0 = 0. Now, -x = f(f(x)) = f(0) = x, which means that x = 0.)

    Further, for any x and y, suppose f(x) = y. We want f(y) = -x then. And f(f(y)) = -y => f(-x) = -y. To summarize: if f(x) = y, then f(-x) = -y, and f(y) = -x, and f(-y) = x.

    So, we need to divide all integers except 0 into sets of 4, but we have an odd number of such integers; not only that, if we remove the integer that doesn't have a positive counterpart, we still have 2(mod4) numbers.

    If we remove the 2 maximal numbers left (by abs value), we can get the function:

    int sign(int n)
    {
        if(n>0)
            return 1;
        else 
            return -1;
    }
    
    int f(int n)
    {
        if(n==0) return 0;
        switch(abs(n)%2)
        {
            case 1:
                 return sign(n)*(abs(n)+1);
            case 0:
                 return -sign(n)*(abs(n)-1);
        }
    }   
    

    Of course another option, is to not comply for 0, and get the 2 numbers we removed as a bonus. (But that's just a silly if.)

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

    I would you change the 2 most significant bits.

    00.... => 01.... => 10.....
    
    01.... => 10.... => 11.....
    
    10.... => 11.... => 00.....
    
    11.... => 00.... => 01.....
    

    As you can see, it's just an addition, leaving out the carried bit.

    How did I got to the answer? My first thought was just a need for symmetry. 4 turns to get back where I started. At first I thought, that's 2bits Gray code. Then I thought actually standard binary is enough.

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

    C# for a range of 2^32 - 1 numbers, all int32 numbers except (Int32.MinValue)

        Func<int, int> f = n =>
            n < 0
               ? (n & (1 << 30)) == (1 << 30) ? (n ^ (1 << 30)) : - (n | (1 << 30))
               : (n & (1 << 30)) == (1 << 30) ? -(n ^ (1 << 30)) : (n | (1 << 30));
    
        Console.WriteLine(f(f(Int32.MinValue + 1))); // -2147483648 + 1
        for (int i = -3; i <= 3  ; i++)
            Console.WriteLine(f(f(i)));
        Console.WriteLine(f(f(Int32.MaxValue))); // 2147483647
    

    prints:

    2147483647
    3
    2
    1
    0
    -1
    -2
    -3
    -2147483647
    
    0 讨论(0)
  • 2020-12-02 03:55

    Exploiting JavaScript exceptions.

    function f(n) {
        try {
            return n();
        }
        catch(e) { 
            return function() { return -n; };
        }
    }
    

    f(f(0)) => 0

    f(f(1)) => -1

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