Mobile Numeric Keypad Problem (original) (raw)
Given a **mobile numeric keypad and an integer n, the task is to find the number of possible unique numeric sequences of length n that can be formed by pressing the keys. The sequences can be built by starting from any digit (0–9) on the keypad.
At each step, you are allowed to press the same key again or move to an adjacent key in the **up, down, left, or right direction. However, **diagonal movements and pressing the **bottom row corner buttons ****(* and #)** are not allowed.

**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
Table of Content
- [Naive Approach] Using Recursion - O(5^n) Time and O(n) Space
- [Better Approach - 1] Using Top-Down DP (Memoization) - O(n) Time and O(n) Space
- [Better Approach - 2] Using Bottom-Up DP (Tabulation) - O(n) Time and O(n) Space
- [Expected Approach] Using Space Optimized DP - O(n) Time and O(1) Space
[Naive Approach] 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++ `
#include #include 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 = 1;
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 = 1;
System.out.println(getCount(n));
}}
Python
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 ansdef 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 ansif name == "main": n = 1 print(getCount(n))
C#
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 = 1;
Console.WriteLine(getCount(n));
}}
JavaScript
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 = 1; console.log(getCount(n));
`
[Better Approach - 1] 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++ `
#include #include using namespace std;
int getCountRecur(int i, int j, int n, vector<vector<vector>> &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 = 1; cout << getCount(n);
return 0;}
Java
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 = 1;
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 ansdef 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 ansif name == "main": n = 1 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 = 1;
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 = 1; console.log(getCount(n));
`
[Better Approach - 2] 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++ `
#include #include 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 = 1; cout << getCount(n); return 0; }
Java
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 = 1;
System.out.println(getCount(n));
}}
Python
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 ansif name == "main": n = 1 print(getCount(n))
C#
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 = 1;
Console.WriteLine(getCount(n));
}}
JavaScript
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 = 1; console.log(getCount(n));
`
[Expected Approach] 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 neighborsfrom 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++ `
#include
#include
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 = 1; cout << getCount(n);
return 0;}
Java
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 = 1;
System.out.println(getCount(n));
}}
Python
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 ansif name == "main": n = 1 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 = 1;
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 = 1; console.log(getCount(n));
`