Reverse factorial

前端 未结 17 1410
南笙
南笙 2020-12-05 03:12

Well, we all know that if N is given it\'s easy to calculate N!. But what about the inverse?

N! is given and you are about to find N - Is that possible ? I\'m curio

相关标签:
17条回答
  • 2020-12-05 03:50
    1. Set X=1.
    2. Generate F=X!
    3. Is F = the input? If yes, then X is N.
    4. If not, then set X=X+1, then start again at #2.

    You can optimize by using the previous result of F to compute the new F (new F = new X * old F).

    It's just as fast as going the opposite direction, if not faster, given that division generally takes longer than multiplication. A given factorial A! is guaranteed to have all integers less than A as factors in addition to A, so you'd spend just as much time factoring those out as you would just computing a running factorial.

    0 讨论(0)
  • 2020-12-05 03:50

    Based on:

    Full inverted factorial valid for x>1

    Use the suggested calculation. If factorial is expressible in full binary form the algorithm is:

    Suppose input is factorial x, x=n!

    1. Return 1 for 1
    2. Find the number of trailing 0's in binary expansion of the factorial x, let us mark it with t
    3. Calculate x/fact(t), x divided by the factorial of t, mathematically x/(t!)
    4. Find how many times x/fact(t) divides t+1, rounded down to the nearest integer, let us mark it with m
    5. Return m+t
    __uint128_t  factorial(int  n);
    
    int invert_factorial(__uint128_t fact)
    {
        if (fact == 1) return 1;
    
        int t = __builtin_ffs(fact)-1;
        int res = fact/factorial(t);
    
        return t + (int)log(res)/log(t+1);
    }
    

    128-bit is giving in on 34!

    0 讨论(0)
  • 2020-12-05 03:53
    int p = 1,i;
    //assume variable fact_n has the value n!
    for(i = 2; p <= fact_n; i++) p = p*i;
    //i is the number you are looking for if p == fact_n else fact_n is not a factorial
    

    I know it isn't a pseudocode, but it's pretty easy to understand

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

    If you do not know whether a number M is N! or not, a decent test is to test if it's divisible by all the small primes until the Sterling approximation of that prime is larger than M. Alternatively, if you have a table of factorials but it doesn't go high enough, you can pick the largest factorial in your table and make sure M is divisible by that.

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

    If you have Q=N! in binary, count the trailing zeros. Call this number J.

    If N is 2K or 2K+1, then J is equal to 2K minus the number of 1's in the binary representation of 2K, so add 1 over and over until the number of 1's you have added is equal to the number of 1's in the result.

    Now you know 2K, and N is either 2K or 2K+1. To tell which one it is, count the factors of the biggest prime (or any prime, really) in 2K+1, and use that to test Q=(2K+1)!.

    For example, suppose Q (in binary) is

    1111001110111010100100110000101011001111100000110110000000000000000000
    

    (Sorry it's so small, but I don't have tools handy to manipulate larger numbers.)

    There are 19 trailing zeros, which is

    10011
    

    Now increment:

    1: 10100
    2: 10101
    3: 10110 bingo!
    

    So N is 22 or 23. I need a prime factor of 23, and, well, I have to pick 23 (it happens that 2K+1 is prime, but I didn't plan that and it isn't needed). So 23^1 should divide 23!, it doesn't divide Q, so

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