Counts paths from a point to reach Origin

Last Updated : 25 Aug, 2026

Geek is standing at a point (x, y) on a 2D grid and wants to reach the origin (0, 0). From any point, Geek can move in only two directions: left, from (x, y) to (x - 1, y), or down, from (x, y) to (x, y - 1).

Find the total number of distinct paths for Geek to reach (0, 0) from (x, y). Since the answer can be very large, return it modulo 1000000007.

Examples: 

Input : x = 3, y = 6
Output : 84
Explanation:

axis

Input: x = 3, y = 0
Output: 1
Explanation:

coordinate-axis
Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(2^(x+y)) Time and O(x+y) Space

We can use Recursion to simulate every possible path.

At any given coordinate, we have two choices:

  • Take a step left
  • Take a step down.

We branch out into both possibilities and add their results together.

If we hit the boundaries (where either the x or y coordinate becomes 0), there is only one straight line left to the origin, so we return 1.

C++
#include <iostream>
using namespace std;

int ways(int x, int y) {
    int mod = 1000000007;

    // Reached a boundary, only one straight path left
    if (x == 0 || y == 0) {
        return 1;
    }

    // Branch into moving left and down
    return (ways(x - 1, y) + ways(x, y - 1)) % mod;
}

int main() {
    int x = 3, y = 6;
    cout << ways(x, y) << endl;
    return 0;
}
Java
class GFG {
    public static int ways(int x, int y) {
        int mod = 1000000007;

        // Reached a boundary, only one straight path left
        if (x == 0 || y == 0) {
            return 1;
        }

        // Branch into moving left and down
        return (ways(x - 1, y) + ways(x, y - 1)) % mod;
    }

    public static void main(String[] args) {
        int x = 3, y = 6;
        System.out.println(ways(x, y));
    }
}
Python
def ways(x, y):
    mod = 1000000007

    # Reached a boundary, only one straight path left
    if x == 0 or y == 0:
        return 1

    # Branch into moving left and down
    return (ways(x - 1, y) + ways(x, y - 1)) % mod

if __name__ == "__main__":
    x = 3
    y = 6
    print(ways(x, y))
C#
using System;

class GFG {
    public static int ways(int x, int y) {
        int mod = 1000000007;

        // Reached a boundary, only one straight path left
        if (x == 0 || y == 0) {
            return 1;
        }

        // Branch into moving left and down
        return (ways(x - 1, y) + ways(x, y - 1)) % mod;
    }

    public static void Main() {
        int x = 3, y = 6;
        Console.WriteLine(ways(x, y));
    }
}
JavaScript
function ways(x, y) {
    let mod = 1000000007;

    // Reached a boundary, only one straight path left
    if (x === 0 || y === 0) {
        return 1;
    }

    // Branch into moving left and down
    return (ways(x - 1, y) + ways(x, y - 1)) % mod;
}

// Driver Code
let x = 3;
let y = 6;
console.log(ways(x, y));

Output
84

[Better Approach] 2D Dynamic Programming - O(x * y) Time and O(x * y) Space

To avoid recalculating the same paths, we can use 2D Dynamic Programming (Tabulation). Think of the grid as a spreadsheet where each cell stores the total number of ways to reach it from the origin.

Since you can only move left or down to reach the origin, working in reverse means to reach cell (i, j) from the origin, you can only come from the cell directly below it (i, j-1) or the cell directly to its left (i-1, j). We can build a 2D matrix where the value of any cell is simply the sum of the cell to its left and the cell below it.

C++
#include <iostream>
#include <vector>
using namespace std;

int ways(int x, int y) {
    int mod = 1000000007;

    // Create a 2D matrix initialized to 0
    vector<vector<int>> dp(x + 1, vector<int>(y + 1, 0));

    // Base cases for borders
    for (int i = 0; i <= x; i++) dp[i][0] = 1;
    for (int j = 0; j <= y; j++) dp[0][j] = 1;

    // Fill the matrix
    for (int i = 1; i <= x; i++) {
        for (int j = 1; j <= y; j++) {

            // Add top and left paths
            dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
        }
    }
    return dp[x][y];
}

int main() {
    int x = 3, y = 6;
    cout << ways(x, y) << endl;
    return 0;
}
Java
class GFG {
    public static int ways(int x, int y) {
        int mod = 1000000007;

        // Create a 2D matrix initialized to 0
        int[][] dp = new int[x + 1][y + 1];

        // Base cases for borders
        for (int i = 0; i <= x; i++) dp[i][0] = 1;
        for (int j = 0; j <= y; j++) dp[0][j] = 1;

        // Fill the matrix
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= y; j++) {

                // Add top and left paths
                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
            }
        }
        return dp[x][y];
    }

    public static void main(String[] args) {
        int x = 3, y = 6;
        System.out.println(ways(x, y));
    }
}
Python
def ways(x, y):
    mod = 1000000007

    # Create a 2D matrix initialized to 0
    dp = [[0] * (y + 1) for _ in range(x + 1)]

    # Base cases for borders
    for i in range(x + 1):
        dp[i][0] = 1
    for j in range(y + 1):
        dp[0][j] = 1

    # Fill the matrix
    for i in range(1, x + 1):
        for j in range(1, y + 1):

            # Add top and left paths
            dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod
            
    return dp[x][y]

if __name__ == "__main__":
    x = 3
    y = 6
    print(ways(x, y))
C#
using System;

class GFG {
    public static int ways(int x, int y) {
        int mod = 1000000007;

        // Create a jagged 2D matrix
        int[][] dp = new int[x + 1][];
        for (int i = 0; i <= x; i++) {
            dp[i] = new int[y + 1];
            dp[i][0] = 1;
        }

        // Base cases for borders
        for (int j = 0; j <= y; j++) {
            dp[0][j] = 1;
        }

        // Fill the matrix
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= y; j++) {

                // Add top and left paths
                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
            }
        }
        return dp[x][y];
    }

    public static void Main() {
        int x = 3, y = 6;
        Console.WriteLine(ways(x, y));
    }
}
JavaScript
function ways(x, y) {
    let mod = 1000000007;

    // Create a 2D matrix initialized to 0
    let dp = Array.from({ length: x + 1 }, () => Array(y + 1).fill(0));

    // Base cases for borders
    for (let i = 0; i <= x; i++) dp[i][0] = 1;
    for (let j = 0; j <= y; j++) dp[0][j] = 1;

    // Fill the matrix
    for (let i = 1; i <= x; i++) {
        for (let j = 1; j <= y; j++) {

            // Add top and left paths
            dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
        }
    }
    return dp[x][y];
}

// Driver Code
let x = 3;
let y = 6;
console.log(ways(x, y));

Output
84

[Expected Approach] Space Optimized DP - O(x * y) Time and O(y) Space

If we look closely at the 2D Dynamic Programming table, computing the current row only requires the values from the immediately preceding row.

We can simplify the logic and optimize the memory by collapsing the 2D grid into a single 1D array representing just one row. As we scan from left to right, we update the array in place.

The value currently at dp[j] represents the cell directly above (from the previous row), and dp[j-1] represents the freshly calculated cell directly to the left. Adding them together gives us the new value for the current cell.

Example: x = 2, y = 2

  • Initialization: Create a 1D array dp of size y + 1 (size 3) and fill it with 1s. This represents row 0. dp = [1, 1, 1].
  • Processing Row 1:
    j = 1: dp[1] = dp[1] + dp[0] = 1 + 1 = 2. dp = [1, 2, 1].
    j = 2: dp[2] = dp[2] + dp[1] = 1 + 2 = 3. dp = [1, 2, 3].
  • Processing Row 2:
    j = 1: dp[1] = dp[1] + dp[0] = 2 + 1 = 3. dp = [1, 3, 3].
    j = 2: dp[2] = dp[2] + dp[1] = 3 + 3 = 6. dp = [1, 3, 6].
  • Result: The loop finishes. The final value at dp[y] is 6. Return 6.
C++
#include <iostream>
#include <vector>
using namespace std;

int ways(int x, int y) {
    int mod = 1000000007;

    // Create a 1D array to store the previous row values
    vector<int> dp(y + 1, 1);

    // Build the paths row by row
    for (int i = 1; i <= x; i++) {
        for (int j = 1; j <= y; j++) {
            
            // Current cell = top cell (dp[j]) + left cell (dp[j-1])
            dp[j] = (dp[j] + dp[j - 1]) % mod;
        }
    }
    return dp[y];
}

int main() {
    int x = 3, y = 6;
    cout << ways(x, y) << endl;
    return 0;
}
Java
import java.util.*;

class GFG {
    public static int ways(int x, int y) {
        int mod = 1000000007;

        // Create a 1D array to store the previous row values
        int[] dp = new int[y + 1];
        Arrays.fill(dp, 1);

        // Build the paths row by row
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= y; j++) {
                
                // Current cell = top cell (dp[j]) + left cell (dp[j-1])
                dp[j] = (dp[j] + dp[j - 1]) % mod;
            }
        }
        return dp[y];
    }

    public static void main(String[] args) {
        int x = 3, y = 6;
        System.out.println(ways(x, y));
    }
}
Python
def ways(x, y):
    mod = 1000000007

    # Create a 1D array to store the previous row values
    dp = [1] * (y + 1)

    # Build the paths row by row
    for i in range(1, x + 1):
        for j in range(1, y + 1):
            
            # Current cell = top cell (dp[j]) + left cell (dp[j-1])
            dp[j] = (dp[j] + dp[j - 1]) % mod

    return dp[y]

if __name__ == "__main__":
    x = 3
    y = 6
    print(ways(x, y))
C#
using System;

class GFG {
    public static int ways(int x, int y) {
        int mod = 1000000007;

        // Create a 1D array to store the previous row values
        int[] dp = new int[y + 1];
        for (int i = 0; i <= y; i++) {
            dp[i] = 1;
        }

        // Build the paths row by row
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= y; j++) {
                
                // Current cell = top cell (dp[j]) + left cell (dp[j-1])
                dp[j] = (dp[j] + dp[j - 1]) % mod;
            }
        }
        return dp[y];
    }

    public static void Main() {
        int x = 3, y = 6;
        Console.WriteLine(ways(x, y));
    }
}
JavaScript
function ways(x, y) {
    let mod = 1000000007;

    // Create a 1D array to store the previous row values
    let dp = new Array(y + 1).fill(1);

    // Build the paths row by row
    for (let i = 1; i <= x; i++) {
        for (let j = 1; j <= y; j++) {
            
            // Current cell = top cell (dp[j]) + left cell (dp[j-1])
            dp[j] = (dp[j] + dp[j - 1]) % mod;
        }
    }
    return dp[y];
}

// Driver Code
let x = 3;
let y = 6;
console.log(ways(x, y));

Output
84

[Optimal Approach] Combinatorics - O(min(x, y) * log(mod)) Time and O(1) Space

To reach (0, 0) from (x, y), Geek must make exactly x left moves and y down moves. The total number of moves will always be exactly x + y. Any valid path is simply a unique arrangement of these x left moves and y down moves.

This translates perfectly to a combinatorics problem: out of the total (x + y) steps, we just need to choose x positions for the left moves (or y positions for the down moves). Mathematically, this is (x + y) C x. To calculate this efficiently under modulo 10^9+7 without overflow, we compute the combinations iteratively and use Fermat's Little Theorem to handle the division (modular multiplicative inverse).

  • Let n = x + y (total moves) and r = min(x, y) (minimum moves to choose, to optimize the loop).
  • Initialize ans = 1.
  • Loop i from 1 to r. In standard math, nCr multiplies by (n - i + 1) and divides by i.
  • Multiply ans by (n - i + 1) and take modulo.
  • Instead of standard division by i, calculate the modular inverse of i using Fermat's Little Theorem: power(i, mod - 2).
  • Multiply ans by this modular inverse and take modulo.
  • After the loop, return the final calculated combination.

For example, x = 2 and y = 2

  • Total moves n = 2 + 2 = 4. We need to choose r = min(2, 2) = 2. We calculate 4C2.
  • Iteration i = 1: Multiply ans by (4 - 1 + 1) = 4. Divide by 1. ans becomes 4.
  • Iteration i = 2: Multiply ans by (4 - 2 + 1) = 3. Divide by 2. ans becomes (4 * 3) / 2 = 6.
  • Result: The loop finishes. The total number of paths is 6.
C++
#include <iostream>
#include <algorithm>
using namespace std;

// Helper to calculate (base^exp) % mod
long long power(long long base, long long exp) {
    long long res = 1;
    long long mod = 1000000007;
    base = base % mod;
    
    while (exp > 0) {
        if (exp % 2 == 1) {
            res = (res * base) % mod;
        }
        base = (base * base) % mod;
        exp /= 2;
    }
    return res;
}

// Helper to find modular inverse using Fermat's Little Theorem
long long modInverse(long long n) {
    return power(n, 1000000007 - 2);
}

int ways(int x, int y) {
    long long mod = 1000000007;
    int n = x + y;
    int r = min(x, y);
    long long ans = 1;

    // Calculate nCr % mod
    for (int i = 1; i <= r; i++) {
        
        // Multiply by (n - i + 1)
        ans = (ans * (n - i + 1)) % mod;
        
        // Divide by i using modular inverse
        ans = (ans * modInverse(i)) % mod;
    }
    
    return (int)ans;
}

int main() {
    int x = 3, y = 6;
    cout << ways(x, y) << endl;
    return 0;
}
Java
class GFG {

    // Helper to calculate (base^exp) % mod
    public static long power(long base, long exp) {
        long res = 1;
        long mod = 1000000007;
        base = base % mod;
        
        while (exp > 0) {
            if (exp % 2 == 1) {
                res = (res * base) % mod;
            }
            base = (base * base) % mod;
            exp /= 2;
        }
        return res;
    }

    // Helper to find modular inverse using Fermat's Little Theorem
    public static long modInverse(long n) {
        return power(n, 1000000007 - 2);
    }

    public static int ways(int x, int y) {
        long mod = 1000000007;
        int n = x + y;
        int r = Math.min(x, y);
        long ans = 1;

        // Calculate nCr % mod
        for (int i = 1; i <= r; i++) {
            
            // Multiply by (n - i + 1)
            ans = (ans * (n - i + 1)) % mod;
            
            // Divide by i using modular inverse
            ans = (ans * modInverse(i)) % mod;
        }
        
        return (int)ans;
    }

    public static void main(String[] args) {
        int x = 3, y = 6;
        System.out.println(ways(x, y));
    }
}
Python
# Helper to calculate (base^exp) % mod
def power(base, exp):
    res = 1
    mod = 1000000007
    base = base % mod
    
    while exp > 0:
        if exp % 2 == 1:
            res = (res * base) % mod
        base = (base * base) % mod
        exp //= 2
        
    return res

# Helper to find modular inverse using Fermat's Little Theorem
def modInverse(n):
    return power(n, 1000000007 - 2)

def ways(x, y):
    mod = 1000000007
    n = x + y
    r = min(x, y)
    ans = 1

    # Calculate nCr % mod
    for i in range(1, r + 1):
        
        # Multiply by (n - i + 1)
        ans = (ans * (n - i + 1)) % mod
        
        # Divide by i using modular inverse
        ans = (ans * modInverse(i)) % mod
        
    return ans

if __name__ == "__main__":
    x = 3
    y = 6
    print(ways(x, y))
C#
using System;

class GFG {

    // Helper to calculate (base^exp) % mod
    public static long Power(long baseVal, long exp) {
        long res = 1;
        long mod = 1000000007;
        baseVal = baseVal % mod;
        
        while (exp > 0) {
            if (exp % 2 == 1) {
                res = (res * baseVal) % mod;
            }
            baseVal = (baseVal * baseVal) % mod;
            exp /= 2;
        }
        return res;
    }

    // Helper to find modular inverse using Fermat's Little Theorem
    public static long ModInverse(long n) {
        return Power(n, 1000000007 - 2);
    }

    public static int ways(int x, int y) {
        long mod = 1000000007;
        int n = x + y;
        int r = Math.Min(x, y);
        long ans = 1;

        // Calculate nCr % mod
        for (int i = 1; i <= r; i++) {
            
            // Multiply by (n - i + 1)
            ans = (ans * (n - i + 1)) % mod;
            
            // Divide by i using modular inverse
            ans = (ans * ModInverse(i)) % mod;
        }
        
        return (int)ans;
    }

    public static void Main() {
        int x = 3, y = 6;
        Console.WriteLine(ways(x, y));
    }
}
JavaScript
// Helper to calculate (base^exp) % mod safely using BigInt
function power(base, exp) {
    let res = 1n;
    let mod = 1000000007n;
    base = BigInt(base) % mod;
    exp = BigInt(exp);
    
    while (exp > 0n) {
        if (exp % 2n === 1n) {
            res = (res * base) % mod;
        }
        base = (base * base) % mod;
        exp /= 2n;
    }
    return res;
}

// Helper to find modular inverse using Fermat's Little Theorem
function modInverse(n) {
    return power(n, 1000000007 - 2);
}

function ways(x, y) {
    let mod = 1000000007n;
    let n = x + y;
    let r = Math.min(x, y);
    let ans = 1n;

    // Calculate nCr % mod
    for (let i = 1; i <= r; i++) {
        let bigI = BigInt(i);
        
        // Multiply by (n - i + 1)
        ans = (ans * BigInt(n - i + 1)) % mod;
        
        // Divide by i using modular inverse
        ans = (ans * modInverse(bigI)) % mod;
    }
    
    return Number(ans);
}

// Driver Code
let x = 3;
let y = 6;
console.log(ways(x, y));

Output
84
Comment