Open In App

Mobile Numeric Keypad Problem

Last Updated : 20 Dec, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a mobile numeric keypad. We can only press the same button or buttons that are up, left, right or down to the current button. Diagonal movements and pressing the bottom row corner buttons (* and #) are not allowed.
Given a number n, find the number of possible unique sequences of length n that we can create by pressing buttons. We can start from any digit.

Mobile-Numeric

Examples:

Input: n = 1
Output: 10
Explanation: The possible outputs are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

Input: n = 2
Output: 36

Using Recursion – O(5^n) Time and O(n) Space

The idea is to use a recursive approach that takes the current cell position (i, j) and the remaining length of the number (n) as input. The base cases are when the current cell is invalid (i.e., outside the keypad or in the bottom row corners) or when the remaining length is 1, in which case we return 1.

For the recursive case, we check all 5 possible next cells (the current cell and the cells up, down, left, and right of it) and recursively call each of them, decrementing the remaining length by 1. The sum of the results from these 5 recursive calls is the answer for the current cell and remaining length.

Mathematically the recurrence relation will look like the following:

getCount(i, j, n) = sum(getCount(x, y, n-1)) where x, y are the next 5 possible cells.

Base Cases:

  • getCount(i, j, n) = 0, if cell is invalid or cell is * or #.
  • getCount(i, j, n) = 1, if n = 1.
C++
// C++ program to implement
// Mobile Numeric Keypad Problem using recursion
#include <bits/stdc++.h>
using namespace std;

int getCountRecur(int i, int j, int n) {

    // Base Case: for invalid cells
    // and * and # cells.
    if (i < 0 || i >= 4 || j < 0 || j >= 3 
        || (i == 3 && (j == 0 || j == 2))) {
        return 0;
    }

    // Base Case
    if (n == 1)
        return 1;

    vector<vector<int>> dir = 
    {{0, 0}, {0, -1}, {0, 1}, {-1, 0}, {1, 0}};

    int ans = 0;

    // Calculate ans for all 5 cells
    for (auto d : dir) {
        int x = i + d[0], y = j + d[1];
        ans += getCountRecur(x, y, n - 1);
    }

    return ans;
}

int getCount(int n) {

    int ans = 0;

    // Calculate ans starting from
    // each cell.
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 3; j++) {
            ans += getCountRecur(i, j, n);
        }
    }

    return ans;
}

int main() {
  
    int n = 3;
    cout << getCount(n);
    return 0;
}
Java
// Java program to implement
// Mobile Numeric Keypad Problem using recursion

class GfG {
    static int getCountRecur(int i, int j, int n) {

        // Base Case: for invalid cells 
        // and * and # cells.
        if (i < 0 || i >= 4 || j < 0 || j >= 3 
            || (i == 3 && (j == 0 || j == 2))) {
            return 0;
        }

        // Base Case
        if (n == 1) return 1;

        int[][] dir = {{0, 0}, {0, -1}, 
         {0, 1}, {-1, 0}, {1, 0}};

        int ans = 0;

        // Calculate ans for all 5 cells
        for (int[] d : dir) {
            int x = i + d[0], y = j + d[1];
            ans += getCountRecur(x, y, n - 1);
        }

        return ans;
    }

    static int getCount(int n) {

        int ans = 0;

        // Calculate ans starting from 
        // each cell.
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += getCountRecur(i, j, n);
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int n = 3;
        System.out.println(getCount(n));
    }
}
Python
# Python program to implement
# Mobile Numeric Keypad Problem using recursion

def getCountRecur(i, j, n):
  
    # Base Case: for invalid cells 
    # and * and # cells.
    if i < 0 or i >= 4 or j < 0 or j >= 3 or\
    (i == 3 and (j == 0 or j == 2)):
        return 0

    # Base Case
    if n == 1:
        return 1

    dir = [[0, 0], [0, -1], [0, 1], [-1, 0], [1, 0]]

    ans = 0

    # Calculate ans for all 5 cells
    for d in dir:
        x, y = i + d[0], j + d[1]
        ans += getCountRecur(x, y, n - 1)

    return ans

def getCount(n):
    ans = 0

    # Calculate ans starting from 
    # each cell.
    for i in range(4):
        for j in range(3):
            ans += getCountRecur(i, j, n)

    return ans

if __name__ == "__main__":
    n = 3
    print(getCount(n))
C#
// C# program to implement
// Mobile Numeric Keypad Problem using recursion

using System;

class GfG {
    static int getCountRecur(int i, int j, int n) {

        // Base Case: for invalid cells 
        // and * and # cells.
        if (i < 0 || i >= 4 || j < 0 || j >= 3 
        || (i == 3 && (j == 0 || j == 2))) {
            return 0;
        }

        // Base Case
        if (n == 1) return 1;

        int[,] dir = { { 0, 0 }, { 0, -1 }, 
         { 0, 1 }, { -1, 0 }, { 1, 0 } };

        int ans = 0;

        // Calculate ans for all 5 cells
        for (int d = 0; d < dir.GetLength(0); d++) {
            int x = i + dir[d, 0], y = j + dir[d, 1];
            ans += getCountRecur(x, y, n - 1);
        }

        return ans;
    }

    static int getCount(int n) {

        int ans = 0;

        // Calculate ans starting from 
        // each cell.
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += getCountRecur(i, j, n);
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int n = 3;
        Console.WriteLine(getCount(n));
    }
}
JavaScript
// JavaScript program to implement
// Mobile Numeric Keypad Problem using recursion

function getCountRecur(i, j, n) {

    // Base Case: for invalid cells 
    // and * and # cells.
    if (i < 0 || i >= 4 || j < 0 || j >= 3 
    || (i === 3 && (j === 0 || j === 2))) {
        return 0;
    }

    // Base Case
    if (n === 1) return 1;

    const dir = [[0, 0], [0, -1], 
    [0, 1], [-1, 0], [1, 0]];

    let ans = 0;

    // Calculate ans for all 5 cells
    for (const d of dir) {
        const x = i + d[0], y = j + d[1];
        ans += getCountRecur(x, y, n - 1);
    }

    return ans;
}

function getCount(n) {
    let ans = 0;

    // Calculate ans starting from 
    // each cell.
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 3; j++) {
            ans += getCountRecur(i, j, n);
        }
    }

    return ans;
}

//driver code
const n = 3;
console.log(getCount(n));

Output
138

Using Top-Down DP (Memoization) – O(n) Time and O(n) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: Number of possible unique sequences of length n at cell (i, j), getCount(i, j, n) depends on the optimal solutions of getCount(x, y, n-1), where x, y are the neighbouring 5 cells.

2. Overlapping Subproblems: While applying a recursive approach in this problem, we notice that certain subproblems are computed multiple times. For example, for getCount(0, 0, 5) and getCount(1, 1, 5), getCount(0, 1, 4) is called twice.

  • There are three parameters: i, j and n that changes in the recursive solution. So we create a 3D matrix of size (n+1)*4*3 for memoization.
  • We initialize this matrix as -1 to indicate nothing is computed initially.
  • Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
C++
// C++ program to implement
// Mobile Numeric Keypad Problem using memoization
#include <bits/stdc++.h>
using namespace std;

int getCountRecur(int i, int j, int n, 
                  vector<vector<vector<int>>> &memo) {

    // Base Case: for invalid cells
    // and * and # cells.
    if (i < 0 || i >= 4 || j < 0 || j >= 3 
        || (i == 3 && (j == 0 || j == 2))) {
        return 0;
    }

    // Base Case
    if (n == 1)
        return 1;

    // If value is memoized
    if (memo[n][i][j] != -1)
        return memo[n][i][j];

    vector<vector<int>> dir = {{0, 0}, {0, -1}, {0, 1}, {-1, 0}, {1, 0}};

    int ans = 0;

    // Calculate ans for all 5 cells
    for (auto d : dir) {
        int x = i + d[0], y = j + d[1];
        ans += getCountRecur(x, y, n - 1, memo);
    }

    return memo[n][i][j] = ans;
}

int getCount(int n) {

    int ans = 0;
    vector<vector<vector<int>>> memo
    (n + 1, vector<vector<int>>(4, vector<int>(3, -1)));

    // Calculate ans starting from
    // each cell.
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 3; j++) {
            ans += getCountRecur(i, j, n, memo);
        }
    }

    return ans;
}

int main() {
    int n = 3;
    cout << getCount(n);

    return 0;
}
Java
// Java program to implement
// Mobile Numeric Keypad Problem using memoization

class GfG {
    static int getCountRecur(int i, int j, int n,
                             int[][][] memo) {

        // Base Case: for invalid cells
        // and * and # cells.
        if (i < 0 || i >= 4 || j < 0 || j >= 3
            || (i == 3 && (j == 0 || j == 2))) {
            return 0;
        }

        // Base Case
        if (n == 1)
            return 1;

        // If value is memoized
        if (memo[n][i][j] != -1)
            return memo[n][i][j];

        int[][] dir = { { 0, 0 },
                        { 0, -1 },
                        { 0, 1 },
                        { -1, 0 },
                        { 1, 0 } };

        int ans = 0;

        // Calculate ans for all 5 cells
        for (int[] d : dir) {
            int x = i + d[0], y = j + d[1];
            ans += getCountRecur(x, y, n - 1, memo);
        }

        return memo[n][i][j] = ans;
    }

    static int getCount(int n) {

        int ans = 0;
        int[][][] memo = new int[n + 1][4][3];
        for (int[][] layer : memo) {
            for (int[] row : layer) {
                java.util.Arrays.fill(row, -1);
            }
        }

        // Calculate ans starting from
        // each cell.
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += getCountRecur(i, j, n, memo);
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int n = 3;
        System.out.println(getCount(n));
    }
}
Python
# Python program to implement
# Mobile Numeric Keypad Problem using memoization

def getCountRecur(i, j, n, memo):
  
    # Base Case: for invalid cells 
    # and * and # cells.
    if i < 0 or i >= 4 or j < 0 or j >= 3 or \
    (i == 3 and (j == 0 or j == 2)):
        return 0

    # Base Case
    if n == 1:
        return 1

    # If value is memoized
    if memo[n][i][j] != -1:
        return memo[n][i][j]

    dir = [[0, 0], [0, -1], [0, 1], [-1, 0], [1, 0]]

    ans = 0

    # Calculate ans for all 5 cells
    for d in dir:
        x, y = i + d[0], j + d[1]
        ans += getCountRecur(x, y, n - 1, memo)

    memo[n][i][j] = ans
    return ans

def getCount(n):
    ans = 0
    memo = [[[-1 for _ in range(3)] for _ in range(4)] for _ in range(n + 1)]

    # Calculate ans starting from 
    # each cell.
    for i in range(4):
        for j in range(3):
            ans += getCountRecur(i, j, n, memo)

    return ans

if __name__ == "__main__":
    n = 3
    print(getCount(n))
C#
// C# program to implement
// Mobile Numeric Keypad Problem using memoization

using System;

class GfG {
    static int getCountRecur(int i, int j, int n,
                             int[, , ] memo) {

        // Base Case: for invalid cells
        // and * and # cells.
        if (i < 0 || i >= 4 || j < 0 || j >= 3
            || (i == 3 && (j == 0 || j == 2))) {
            return 0;
        }

        // Base Case
        if (n == 1)
            return 1;

        // If value is memoized
        if (memo[n, i, j] != -1)
            return memo[n, i, j];

        int[, ] dir = { { 0, 0 },
                        { 0, -1 },
                        { 0, 1 },
                        { -1, 0 },
                        { 1, 0 } };

        int ans = 0;

        // Calculate ans for all 5 cells
        for (int d = 0; d < dir.GetLength(0); d++) {
            int x = i + dir[d, 0], y = j + dir[d, 1];
            ans += getCountRecur(x, y, n - 1, memo);
        }

        return memo[n, i, j] = ans;
    }

    static int getCount(int n) {

        int ans = 0;
        int[, , ] memo = new int[n + 1, 4, 3];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j < 4; j++) {
                for (int k = 0; k < 3; k++) {
                    memo[i, j, k] = -1;
                }
            }
        }

        // Calculate ans starting from
        // each cell.
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += getCountRecur(i, j, n, memo);
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int n = 3;
        Console.WriteLine(getCount(n));
    }
}
JavaScript
// JavaScript program to implement
// Mobile Numeric Keypad Problem using memoization

function getCountRecur(i, j, n, memo) {

    // Base Case: for invalid cells
    // and * and # cells.
    if (i < 0 || i >= 4 || j < 0 || j >= 3
        || (i === 3 && (j === 0 || j === 2))) {
        return 0;
    }

    // Base Case
    if (n === 1)
        return 1;

    // If value is memoized
    if (memo[n][i][j] !== -1)
        return memo[n][i][j];

    const dir = [
        [ 0, 0 ], [ 0, -1 ], [ 0, 1 ], [ -1, 0 ], [ 1, 0 ]
    ];

    let ans = 0;

    // Calculate ans for all 5 cells
    for (const d of dir) {
        const x = i + d[0], y = j + d[1];
        ans += getCountRecur(x, y, n - 1, memo);
    }

    return (memo[n][i][j] = ans);
}

function getCount(n) {
    const memo = Array.from(
        {length : n + 1},
        () => Array.from({length : 4},
                         () => Array(3).fill(-1)));

    let ans = 0;

    // Calculate ans starting from
    // each cell.
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 3; j++) {
            ans += getCountRecur(i, j, n, memo);
        }
    }

    return ans;
}

//driver code
const n = 3;
console.log(getCount(n));

Output
138

Using Bottom-Up DP (Tabulation) – O(n) Time and O(n) Space

We use a 3D array dp[k][i][j], where k represents the length of the sequence, and i and j represent the row and column of the keypad, respectively. The DP array is of size (n+1) x 4 x 3, where n is the length of the sequence. The idea is to fill the table iteratively, starting from sequences of length 1 (which is initialized with 1 for all keys, except * and #) and then for each subsequent length, compute the possible sequences by considering adjacent keys (up, down, left, right).

C++
// C++ program to implement
// Mobile Numeric Keypad Problem using tabulation
#include <bits/stdc++.h>
using namespace std;

int getCount(int n) {

    int ans = 0;
    vector<vector<vector<int>>> 
    dp(n + 1, vector<vector<int>>(4, vector<int>(3, 0)));

    // Set dp[1][i][j] = 1
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 3; j++) {
            dp[1][i][j] = 1;
        }
    }
    dp[1][3][0] = 0;
    dp[1][3][2] = 0;

    vector<vector<int>> dir = 
    {{0, 0}, {0, -1}, {0, 1}, {-1, 0}, {1, 0}};

    for (int k = 2; k <= n; k++) {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {

                // For cell * and #
                if (i == 3 && (j == 0 || j == 2)) {
                    continue;
                }

                // Check for all 5 next cells
                for (auto d : dir) {
                    int x = i + d[0], y = j + d[1];
                    if (x >= 0 && x < 4 && y >= 0 && y < 3) {
                        dp[k][i][j] += dp[k - 1][x][y];
                    }
                }
            }
        }
    }

    // Add ans from each cell
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 3; j++) {
            ans += dp[n][i][j];
        }
    }

    return ans;
}

int main() {
    int n = 3;
    cout << getCount(n);
    return 0;
}
Java
// Java program to implement
// Mobile Numeric Keypad Problem using tabulation

class GfG {

    static int getCount(int n) {
        int ans = 0;
        int[][][] dp = new int[n + 1][4][3];

        // Set dp[1][i][j] = 1
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                dp[1][i][j] = 1;
            }
        }
        dp[1][3][0] = 0;
        dp[1][3][2] = 0;

        int[][] dir = { { 0, 0 },
                        { 0, -1 },
                        { 0, 1 },
                        { -1, 0 },
                        { 1, 0 } };

        for (int k = 2; k <= n; k++) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {

                    // For cell * and #
                    if (i == 3 && (j == 0 || j == 2)) {
                        continue;
                    }

                    // Check for all 5 next cells
                    for (int[] d : dir) {
                        int x = i + d[0], y = j + d[1];
                        if (x >= 0 && x < 4 && y >= 0
                            && y < 3) {
                            dp[k][i][j] += dp[k - 1][x][y];
                        }
                    }
                }
            }
        }

        // Add ans from each cell
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += dp[n][i][j];
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int n = 3;
        System.out.println(getCount(n));
    }
}
Python
# Python program to implement
# Mobile Numeric Keypad Problem using tabulation

def getCount(n):
    ans = 0
    dp = [[[0 for _ in range(3)] for _ in range(4)] for _ in range(n + 1)]

    # Set dp[1][i][j] = 1
    for i in range(4):
        for j in range(3):
            dp[1][i][j] = 1
    dp[1][3][0] = 0
    dp[1][3][2] = 0

    dir = [[0, 0], [0, -1], [0, 1], [-1, 0], [1, 0]]

    for k in range(2, n + 1):
        for i in range(4):
            for j in range(3):

                # For cell * and #
                if i == 3 and (j == 0 or j == 2):
                    continue

                # Check for all 5 next cells
                for d in dir:
                    x, y = i + d[0], j + d[1]
                    if 0 <= x < 4 and 0 <= y < 3:
                        dp[k][i][j] += dp[k - 1][x][y]

    # Add ans from each cell
    for i in range(4):
        for j in range(3):
            ans += dp[n][i][j]

    return ans

if __name__ == "__main__":
    n = 3
    print(getCount(n))
C#
// C# program to implement
// Mobile Numeric Keypad Problem using tabulation

using System;

class GfG {
    static int getCount(int n) {
        int ans = 0;
        int[, , ] dp = new int[n + 1, 4, 3];

        // Set dp[1][i][j] = 1
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                dp[1, i, j] = 1;
            }
        }
        dp[1, 3, 0] = 0;
        dp[1, 3, 2] = 0;

        int[, ] dir = { { 0, 0 },
                        { 0, -1 },
                        { 0, 1 },
                        { -1, 0 },
                        { 1, 0 } };

        for (int k = 2; k <= n; k++) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {

                    // For cell * and #
                    if (i == 3 && (j == 0 || j == 2)) {
                        continue;
                    }

                    // Check for all 5 next cells
                    for (int d = 0; d < 5; d++) {
                        int x = i + dir[d, 0],
                            y = j + dir[d, 1];
                        if (x >= 0 && x < 4 && y >= 0
                            && y < 3) {
                            dp[k, i, j] += dp[k - 1, x, y];
                        }
                    }
                }
            }
        }

        // Add ans from each cell
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += dp[n, i, j];
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int n = 3;
        Console.WriteLine(getCount(n));
    }
}
JavaScript
// JavaScript program to implement
// Mobile Numeric Keypad Problem using tabulation

function getCount(n) {
    let ans = 0;
    let dp = Array.from(
        {length : n + 1},
        () => Array.from({length : 4},
                         () => Array(3).fill(0)));

    // Set dp[1][i][j] = 1
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 3; j++) {
            dp[1][i][j] = 1;
        }
    }
    dp[1][3][0] = 0;
    dp[1][3][2] = 0;

    let dir = [
        [ 0, 0 ], [ 0, -1 ], [ 0, 1 ], [ -1, 0 ], [ 1, 0 ]
    ];

    for (let k = 2; k <= n; k++) {
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 3; j++) {

                // For cell * and #
                if (i === 3 && (j === 0 || j === 2)) {
                    continue;
                }

                // Check for all 5 next cells
                for (let d of dir) {
                    let x = i + d[0], y = j + d[1];
                    if (x >= 0 && x < 4 && y >= 0
                        && y < 3) {
                        dp[k][i][j] += dp[k - 1][x][y];
                    }
                }
            }
        }
    }

    // Add ans from each cell
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 3; j++) {
            ans += dp[n][i][j];
        }
    }

    return ans;
}

//driver code
let n = 3;
console.log(getCount(n));

Output
138

Using Space Optimized DP – O(n) Time and O(1) Space

We only need to maintain two 2D arrays, prev and curr, to track the state of each key on the keypad at each step. Initially, all keys are assumed to be reachable in one move, except for the corner keys * and #, which are set to 0. Then, for each step from 2 to n, calculate the number of ways to reach each key by considering its valid neighbors from the previous step.

After updating the curr array for each step, we copy its values to prev for use in the next iteration. Finally, we sum the values in prev after n steps to get the total number of unique sequences of length n that can be formed.

C++
// C++ program to implement Mobile Numeric Keypad Problem
// using space optimised dp
#include <bits/stdc++.h>
using namespace std;

int getCount(int n) {

    int ans = 0;
    vector<vector<int>> prev(4, vector<int>(3, 1));
    prev[3][0] = 0;
    prev[3][2] = 0;

    // matrix to store current states
    vector<vector<int>> curr(4, vector<int>(3));

    vector<vector<int>> dir = 
    {{0, 0}, {0, -1}, {0, 1}, {-1, 0}, {1, 0}};

    for (int k = 2; k <= n; k++) {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                curr[i][j] = 0;

                // For cell * and #
                if (i == 3 && (j == 0 || j == 2)) {
                    continue;
                }

                // Check for all 5 next cells
                for (auto d : dir) {
                    int x = i + d[0], y = j + d[1];
                    if (x >= 0 && x < 4 && y >= 0 && y < 3) {
                        curr[i][j] += prev[x][y];
                    }
                }
            }
        }

        // Update previous states
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                prev[i][j] = curr[i][j];
            }
        }
    }

    // Add ans from each cell
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 3; j++) {
            ans += prev[i][j];
        }
    }

    return ans;
}

int main() {
    int n = 3;
    cout << getCount(n);

    return 0;
}
Java
// Java program to implement Mobile Numeric Keypad Problem
// using space optimised dp
import java.util.*;

class GfG {

    static int getCount(int n) {
        int ans = 0;

        int[][] prev = new int[4][3];
        for (int i = 0; i < 4; i++) {
            Arrays.fill(prev[i], 1);
        }
        prev[3][0] = 0;
        prev[3][2] = 0;

        int[][] curr = new int[4][3];
        int[][] dir = {{0, 0}, {0, -1}, {0, 1}, {-1, 0}, {1, 0}};

        for (int k = 2; k <= n; k++) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {
                    curr[i][j] = 0;

                    // For cell * and #
                    if (i == 3 && (j == 0 || j == 2)) {
                        continue;
                    }

                    // Check for all 5 next cells
                    for (int[] d : dir) {
                        int x = i + d[0], y = j + d[1];
                        if (x >= 0 && x < 4 && y >= 0 && y < 3) {
                            curr[i][j] += prev[x][y];
                        }
                    }
                }
            }

            // Update previous states
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {
                    prev[i][j] = curr[i][j];
                }
            }
        }

        // Add ans from each cell 
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += prev[i][j];
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int n = 3;
        System.out.println(getCount(n));
    }
}
Python
# Python program to implement Mobile Numeric Keypad Problem
# using space optimised dp
def getCount(n):
    ans = 0

    prev = [[1 for _ in range(3)] for _ in range(4)]
    prev[3][0] = 0
    prev[3][2] = 0

    curr = [[0 for _ in range(3)] for _ in range(4)]
    dir = [[0, 0], [0, -1], [0, 1], [-1, 0], [1, 0]]

    for k in range(2, n + 1):
        for i in range(4):
            for j in range(3):
                curr[i][j] = 0

                # For cell * and #
                if i == 3 and (j == 0 or j == 2):
                    continue

                # Check for all 5 next cells
                for d in dir:
                    x, y = i + d[0], j + d[1]
                    if 0 <= x < 4 and 0 <= y < 3:
                        curr[i][j] += prev[x][y]

        # Update previous states
        for i in range(4):
            for j in range(3):
                prev[i][j] = curr[i][j]

    # Add ans from each cell
    for i in range(4):
        for j in range(3):
            ans += prev[i][j]

    return ans


if __name__ == "__main__":
    n = 3
    print(getCount(n))
C#
// C# program to implement Mobile Numeric Keypad Problem
// using space optimised dp
using System;

class GfG {

    static int getCount(int n) {
        int ans = 0;

        int[, ] prev = new int[4, 3];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                prev[i, j] = 1;
            }
        }
        prev[3, 0] = 0;
        prev[3, 2] = 0;

        int[, ] curr = new int[4, 3];
        int[, ] dir = { { 0, 0 },
                        { 0, -1 },
                        { 0, 1 },
                        { -1, 0 },
                        { 1, 0 } };

        for (int k = 2; k <= n; k++) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {
                    curr[i, j] = 0;

                    // For cell * and #
                    if (i == 3 && (j == 0 || j == 2)) {
                        continue;
                    }

                    // Check for all 5 next cells
                    for (int d = 0; d < 5; d++) {
                        int x = i + dir[d, 0],
                            y = j + dir[d, 1];
                        if (x >= 0 && x < 4 && y >= 0
                            && y < 3) {
                            curr[i, j] += prev[x, y];
                        }
                    }
                }
            }

            // Update previous states
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {
                    prev[i, j] = curr[i, j];
                }
            }
        }

        // Add ans from each cell
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                ans += prev[i, j];
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int n = 3;
        Console.WriteLine(getCount(n));
    }
}
JavaScript
// Javascript program to implement Mobile Numeric Keypad
// Problem using space optimised dp

function getCount(n) {
    let ans = 0;

    let prev
        = Array.from({length : 4}, () => Array(3).fill(1));
    prev[3][0] = 0;
    prev[3][2] = 0;

    let curr
        = Array.from({length : 4}, () => Array(3).fill(0));
    let dir = [
        [ 0, 0 ], [ 0, -1 ], [ 0, 1 ], [ -1, 0 ], [ 1, 0 ]
    ];

    for (let k = 2; k <= n; k++) {
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 3; j++) {
                curr[i][j] = 0;

                // For cell * and #
                if (i === 3 && (j === 0 || j === 2)) {
                    continue;
                }

                // Check for all 5 next cells
                for (let d of dir) {
                    let x = i + d[0], y = j + d[1];
                    if (x >= 0 && x < 4 && y >= 0
                        && y < 3) {
                        curr[i][j] += prev[x][y];
                    }
                }
            }
        }

        // Update previous states
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 3; j++) {
                prev[i][j] = curr[i][j];
            }
        }
    }

    // Add ans from each cell
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 3; j++) {
            ans += prev[i][j];
        }
    }

    return ans;
}

//driver code
let n = 3;
console.log(getCount(n));

Output
138


Next Article

Similar Reads