Happy traveller [Part 1]

There is a play grid NxN; Always square! 

   0  1  2  3
0 [o, o, o, X]
1 [o, o, o, o]
2 [o, o, o, o]
3 [o, o, o, o]


You start from a random point. I mean, you are given the coordinates of your start position in format (row, col). 

And your TASK is to define the number of unique paths to reach position X (always in the top right corner).


From any point you can go only UP or RIGHT.


Implement a function count_paths(N, (row, col)) which returns int; 
Assume input params are always valid.


Example:

count_paths(1, (0, 0))
grid 1x1:

[X]
 You are already in the target point, so return 0


count_paths(2, (1, 0))
grid 2x2:

[o, X]
[@, o]
 You are at point @; you can move UP-RIGHT or RIGHT-UP, and there are 2 possible unique paths here

count_paths(2, (1, 1))
grid 2x2:

[o, X]
[o, @]
 You are at point @; you can move only UP, so there is 1 possible unique path here

count_paths(3, (1, 0))
grid 3x3:

[o, o, X]
[@, o, o]
[o, o, o]
 You are at point @; you can move UP-RIGHT-RIGHT or RIGHT-UP-RIGHT, or RIGHT-RIGHT-UP, and there are 3 possible unique paths here


I think it's pretty clear =)

btw. you can use preloaded Grid class, which constructs 2d array for you. It's very very basic and simple. You can use numpy instead or any other way to produce the correct answer =)
 grid = Grid(2, 2, 0) 
samegrid = Grid.square(2) will give you a grid[2][2], which you can print easily to console. 

print(grid)


[0, 0]
[0, 0]


Enjoy!

You can continue adventures:
Happy traveller [Part 2]

Difficulty: introductory

Starter code:

def count_paths(N, coords):
	

Solutions:
from math import factorial as f
count_paths=lambda n,c:f(c[0]+abs(n-c[1]-1))//(f(abs(n-c[1]-1))*f(c[0])) if n!=1 else 0

from math import factorial
def count_paths(N, coords):
    if N==1:
        return 0
    x=coords[0]
    y=N-1-coords[1]
    return factorial(x+y)//(factorial(x)*factorial(y))

count_paths=lambda n,C,f=__import__('math').factorial:(n!=1)*f(n+C[0]-1-C[1])//f(C[0])//f(n-1-C[1])

def count_paths(N,C,f=lambda n:eval('*'.join(map(str,range(1,n+1))))):
    a,y=C
    b=N-1-y
    return 1-(b==0)if a==0else 1-(a==0)if b==0 else f(a+b)//f(a)//f(b) 

import math
def count_paths(N, coords):
    t = N-1 - coords[1] + coords[0]
    if t == 0:
        return 0
    
    return math.factorial(t)//(math.factorial(coords[0])*math.factorial(t-coords[0]))

import math

# if you look at the matrix of possible paths...
# [ 1,  1,  1,  0]
# [ 4,  3,  2,  1]
# [10,  6,  3,  1]
# [20, 10,  4,  1]
# ...the diagonals reflect Pascal's triangle.
#
# For example, 4C1 = 4, 4C2 = 6, 4C3 = 4
# Each cell (row, col) has possible paths = dC(l-row) where:
#    d = the ordinal of the diagonal (zero-indexed)
#    l = the length of the diagonal
#
# We can calculate d and l like so:
#    d = row + n - 1 - col
#    l = d + 1
#
# Combined, we get:
#    (row + n - 1 - col) C (n - 1 - col)
def count_paths(N, coords):
    row, col = coords
    if row == 0 and col == N-1:
        return 0
    
    inverse_col = N - 1 - col
    return choose(row + inverse_col, inverse_col)

# aCb = a!/(a-b)!b!
def choose(n,k):
    if k > n:
        return 0
    if k > n-k:
        k = n-k
    product = 1
    k_list = list(range(2, k+1))
    for i in range(n, n-k, -1):
        if len(k_list) > 0:
            k_index = len(k_list)-1
            k = k_list[k_index]
            if i % k == 0:
                i = i // k
                del k_list[k_index]
        product *= i
    for k in k_list:
        product //= k
    return product

from math import factorial as f
bino=lambda x,y: f(x)//f(y)//f(x-y)

def count_paths(N, coords):
    d1,d2 = N - coords[1] - 1, coords[0]
    return bino(d1+d2,min(d1,d2)) if d1+d2 else 0