0

I need a function that can solve the following: for a binomial function nCr=k, given r and k find n. in mathematics nCr=n!/r!(n-r)! I tried following but it doesn't solve it. for example 8C6=28, for my function the inputs are 6 and 28 and i want to find 8. This may not have exact integer number so I want to find an x>=n.

"""
I am approaching it this way, i.e. find the solution of a polynomial function  iteratively, hope there is a better way"""
"""I am approaching it this way, i.e. find the solution of a polynomial function iteratively, hope there is a better way"""
def find_n(r,k):
    #solve_for_n_in(n*(n-1)...(n-r)=math.factorial(r)*k
    #in the above example solve_for_n(n*(n-1)(n-2)(n-3)(n-4)(n-5)=720*28)

    sum=math.factorial(r)*k
    n=r
    p=1
    while p<sum: 
        p=1
        for i in range(0,r+2):
            p*=(n-i+1)
        n+=1
    return n

Thanks.

  • Just do the math properly... your idea is obviously to store n/(n-r)! in "sum" and compare it to r!k, but "sum" is computed wrong. In the first iteration sum equals n, then (n-1)^2, then (n-2)^2*(n-1), and so on... – Jochen Müller Mar 03 '16 at 11:05
  • 1
    Possible duplicate of [For binomial function nCr=k, given r and k find n](http://stackoverflow.com/questions/35753215/for-binomial-function-ncr-k-given-r-and-k-find-n) – Debosmit Ray Mar 03 '16 at 11:20
  • hi @jomuel i modified it and but it doesn't get results sometimes. – white_chick Mar 03 '16 at 17:43

3 Answers3

0

I spot a mistake in your code.

sum=n

You're setting sum to n then,

while sum<factorial(r)*k:
    sum*=n

You're multiplying sum by n again. so now sum = n**2. this would be better:

  while sum<factorial(r)*k:
    n+=1
    sum*=n
junoon53
  • 41
  • 2
0

This is just an idea of how this problem could be approached, while maintaining a high degree of readability.

nCr = n! / {{r!}{n-r}!} = n(n-1)...(n-r+1) / {r!} The right hand side is some value k.

Start with n = 2*(r+1).

nCr < RHS => n is too small => increase n

nCr > RHS => n is too big => decrease n

nCr == RHS => found n

... ... Keep doing this till you find n or something goes wrong.

import math

def find_n(r,k):

    if k==1:
        return r         # RHS is 1 when n and r are the same

    RHS = math.factorial(r) * k

    possible_n = 2 * r;
    possible_numerator = math.factorial(possible_n)
    possible_denom = math.factorial(possible_n - r)

    while True:
        # current n is too small 
        if ( possible_numerator // possible_denom ) < RHS:
            # try possible_n + 1
            possible_n = possible_n + 1
            possible_numerator = math.factorial(possible_n)
            possible_denom = math.factorial(possible_n - r)

        elif ( possible_numerator // possible_denom ) > RHS:
            # try possible_n - 1
            possible_n = possible_n - 1
            possible_numerator = math.factorial(possible_n)
            possible_denom = math.factorial(possible_n - r)

        elif ( possible_n == r):
            print ("***n smaller than r***");
            sys.exit(0);

        elif ( possible_numerator // possible_denom ) == RHS:
            return possible_n





print( find_n(6, 28) )      # should print 8

print( find_n(6, 462) )     # should print 11 

print( find_n(6, 3003) )        # should print 14

print( find_n(5, 3003) )        # should print 15
Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
  • If performance is of concern, start caching values of the factorials in a map or an array or something. – Debosmit Ray Mar 03 '16 at 21:44
  • first inspiration came when you mentioned `x>=n`. Now, it didn't make a whole lot of sense starting the search from `r+1` since that wouldn't help a lot if you start to cache values in a map. `2*r+1` wouldn't matter much if `r` was small, but as the size of `r` grows, the factorials would get expensive and the caching would let you get the factorials in essentially O(1). This seems like the simplest way to go, keeping readability in mind. – Debosmit Ray Mar 04 '16 at 09:52
  • if you start caching factorial values from r+1 and go on, you will run out of heap space very soon (tested in Java). So, it wouldn't be scalable. – Debosmit Ray Mar 04 '16 at 09:54
0

I used a function that calculates the binomial coefficient to implement the feature nCr

def binomial(n,k):
    return 1 if k==0 else (0 if n==0 else binomial(n-1, k) + binomial(n-1, k-1))

def nCr(r,c):
    n=0
    b=binomial(n,r)
    while b<c:
        n=n+1
        b=binomial(n,r)
        if b==c:
            return n

    return None

nCr(6,28)

8

merrais
  • 371
  • 2
  • 9