This is similar to Pascal's triangle. Reaching each point on the grid requires the sum of paths of the positions above and to the left up to the main diagonal (Pascal's progression) and then down to the destination.
2x2
Pascal's Rest
*--1--1 *--1--1
| | | | | |
1--2--+ 1--2--3
| | | | | |
1--+--+ 1--3--6 ==> 6 paths
3x3
Pascal's Rest
*--1--1--1 *--1--1--1
| | | | | | | |
1--2--3--+ 1--2--3--4
| | | | | | | |
1--3--+--+ 1--3--6--10
| | | | | | | |
1--+--+--+ 1--4--10-20 ==> 20 paths
4x4
Pascal's rest
*--1--1--1--1 *--1--1--1--1
| | | | | | | | | |
1--2--3--4--+ 1--2--3--4--5
| | | | | | | | | |
1--3--6--+--+ 1--3--6--10-15
| | | | | | | | | |
1--4--+--+--+ 1--4--10-20-35
| | | | | | | | | |
1--+--+--+--+ 1--5--15-35-70 ==> 70 paths
At this point, you could do more math or you could implement an efficient algorithm to compute the result:
N = 4
paths = [1]
for _ in range(N):
paths = [ a+b for a,b in zip(paths,[0]+paths) ]+[1] # Pascal's
for _ in range(N):
paths = [ a+b for a,b in zip(paths,paths[1:]) ] # Rest
result = paths[0]
More Math: If you expand the square to 2N, you will also notice that the result is the point exactly in the middle of the main diagonal. This is the Nth value on line 2N of Pascal's triangle.
*--1--1--1--1··1··1··1··1
| | | | | : : :
1--2--3--4--5··+··+··8··
| | | | | : :
1--3--6--10-15·+··28··
| | | | | :
1--4--10-20-35·56··
| | | | |
1--5--15-35-70·· <-- 70 is combinations of 4 in 8
: : : :
1··+··+··56··
: : :
1··+··28··
: :
1··8··
:
1··
In accordance with properties of Pascal's triangle, this is equivalent to the number of combinations of N values in a set of 2N.
It can be calculated by (2N)! / N!^2: factorial(2*N)//factorial(N)**2
N=2 --> 4!/2!^2 --> 24/4 --> 6
N=3 --> 6!/3!^2 --> 720/36 --> 20
N=4 --> 8!/4!^2 --> 40320/576 --> 70
...
N=20 --> you do the math :)