Open In App

Count of distinct Numbers that can be formed by chess knight in N moves on a mobile keypad

Last Updated : 17 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer N and a chess knight placed in mobile keypad. The task is to count the total distinct N digit numbers which can be formed by the chess knight with N moves. As the answer can be very large give the value of answer modulo 109 + 7.

Note: In each move a chess knight can move 2 units horizontally and one unit vertically or two units vertically and one unit horizontally.

A demo mobile keypad is shown in image where ‘*’ and ‘#’ are not considered as part of a number.

Examples:

Input: N = 1
Output: 10
Explanation: Placing the knight over any numeric cell of the 10 cells is sufficient.

Input: N = 2
Output: 20
Explanation: All the valid number are [04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]

 

Approach: The idea is to find the possible cells that can be reached from a given cell for every cell and add all of them to find the answer. Follow the steps below to solve the problem:

  • Initialize the vector v[10, 1], and temp[10].
  • Iterate over the range [1, N) using the variable i and perform the following tasks:
    • Find the values for all cells in temp[] and then store them in vector v[].
  • Initialize the variable sum as 0 to store the answer.
  • Iterate over the range [0, 10) using the variable i and perform the following tasks:
    • Add the value of v[i] to the variable sum.
  • After performing the above steps, print the value of sum as the answer.

Below is the implementation of the above approach.

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the total number of ways
int knightCalling(int N)
{
    int mod = 1000000007;
 
    // Base Case
    if (N == 1)
        return 10;
    vector<int> v(10, 1);
    vector<int> temp(10);
 
    // No cell can be reached from a
    // cell with value 5
    v[5] = 0;
    for (int i = 1; i < N; i++)
    {
       
        // Find the possible values from all cells
        temp[0] = (v[4] + v[6]) % mod;
        temp[1] = (v[6] + v[8]) % mod;
        temp[2] = (v[7] + v[9]) % mod;
        temp[3] = (v[4] + v[8]) % mod;
        temp[4] = (v[0] + v[3] + v[9]) % mod;
        temp[6] = (v[0] + v[1] + v[7]) % mod;
        temp[7] = (v[2] + v[6]) % mod;
        temp[8] = (v[1] + v[3]) % mod;
        temp[9] = (v[2] + v[4]) % mod;
 
        // Store them
        for (int j = 0; j < 10; j++)
            v[j] = temp[i];
    }
 
    // Find the answer
    int sum = 0;
    for (int i = 0; i < 10; i++)
        sum = (sum + v[i]) % mod;
    return sum;
}
 
// Driver Code
int main()
{
    int N = 2;
    cout << knightCalling(N);
}
 
// This code is contributed by Samim Hossain Mondal.


Java




// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to find the total number of ways
static int knightCalling(int N)
{
    int mod = 1000000007;
 
    // Base Case
    if (N == 1)
        return 10;
    int []v = new int[10];
    int []temp = new int[10];
    Arrays.fill(v, 1);
 
    // No cell can be reached from a
    // cell with value 5
    v[5] = 0;
    for (int i = 1; i < N; i++)
    {
       
        // Find the possible values from all cells
        temp[0] = (v[4] + v[6]) % mod;
        temp[1] = (v[6] + v[8]) % mod;
        temp[2] = (v[7] + v[9]) % mod;
        temp[3] = (v[4] + v[8]) % mod;
        temp[4] = (v[0] + v[3] + v[9]) % mod;
        temp[6] = (v[0] + v[1] + v[7]) % mod;
        temp[7] = (v[2] + v[6]) % mod;
        temp[8] = (v[1] + v[3]) % mod;
        temp[9] = (v[2] + v[4]) % mod;
 
        // Store them
        for (int j = 0; j < 10; j++)
            v[i] = temp[i];
    }
 
    // Find the answer
    int sum = 0;
    for (int i = 0; i < 10; i++)
        sum = (sum + v[i]) % mod;
    return sum;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 2;
    System.out.print(knightCalling(N));
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python 3  program for the above approach
 
# Function to find the total number of ways
def knightCalling(N):
 
    mod = 1000000007
 
    # Base Case
    if (N == 1):
        return 10
    v = [1]*10
    temp = [0]*10
 
    # No cell can be reached from a
    # cell with value 5
    v[5] = 0
    for i in range(1, N):
       
        # Find the possible values from all cells
        temp[0] = (v[4] + v[6]) % mod
        temp[1] = (v[6] + v[8]) % mod
        temp[2] = (v[7] + v[9]) % mod
        temp[3] = (v[4] + v[8]) % mod
        temp[4] = (v[0] + v[3] + v[9]) % mod
        temp[6] = (v[0] + v[1] + v[7]) % mod
        temp[7] = (v[2] + v[6]) % mod
        temp[8] = (v[1] + v[3]) % mod
        temp[9] = (v[2] + v[4]) % mod
 
        # Store them
        for j in range(10):
            v[j] = temp[j]
 
    # Find the answer
    sum = 0
    for i in range(10):
        sum = (sum + v[i]) % mod
    return sum
 
# Driver Code
if __name__ == "__main__":
 
    N = 2
    print(knightCalling(N))
 
    # This code is contributed by ukasp.


C#




// C# program for the above approach
using System;
class GFG{
 
  // Function to find the total number of ways
  static int knightCalling(int N)
  {
    int mod = 1000000007;
 
    // Base Case
    if (N == 1)
      return 10;
    int []v = new int[10];
    int []temp = new int[10];
    for(int i = 0; i < 10; i++) {
      v[i] = 1;
    }
 
    // No cell can be reached from a
    // cell with value 5
    v[5] = 0;
    for (int i = 1; i < N; i++)
    {
 
      // Find the possible values from all cells
      temp[0] = (v[4] + v[6]) % mod;
      temp[1] = (v[6] + v[8]) % mod;
      temp[2] = (v[7] + v[9]) % mod;
      temp[3] = (v[4] + v[8]) % mod;
      temp[4] = (v[0] + v[3] + v[9]) % mod;
      temp[6] = (v[0] + v[1] + v[7]) % mod;
      temp[7] = (v[2] + v[6]) % mod;
      temp[8] = (v[1] + v[3]) % mod;
      temp[9] = (v[2] + v[4]) % mod;
 
      // Store them
      for (int j = 0; j < 10; j++)
        v[j] = temp[i];
    }
 
    // Find the answer
    int sum = 0;
    for (int i = 0; i < 10; i++)
      sum = (sum + v[i]) % mod;
    return sum;
  }
 
  // Driver Code
  public static void Main()
  {
    int N = 2;
    Console.Write(knightCalling(N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
       // JavaScript code for the above approach
 
       // Function to find the total number of ways
       function knightCalling(N) {
           let mod = 1000000007;
 
           // Base Case
           if (N == 1)
               return 10;
           let v = new Array(10).fill(1)
           let temp = new Array(10).fill(0);
 
           // No cell can be reached from a
           // cell with value 5
           v[5] = 0;
           for (let i = 1; i < N; i++)
           {
            
               // Find the possible values from all cells
               temp[0] = (v[4] + v[6]) % mod;
               temp[1] = (v[6] + v[8]) % mod;
               temp[2] = (v[7] + v[9]) % mod;
               temp[3] = (v[4] + v[8]) % mod;
               temp[4] = (v[0] + v[3] + v[9]) % mod;
               temp[6] = (v[0] + v[1] + v[7]) % mod;
               temp[7] = (v[2] + v[6]) % mod;
               temp[8] = (v[1] + v[3]) % mod;
               temp[9] = (v[2] + v[4]) % mod;
 
               // Store them
               for (let i = 0; i < 10; i++)
                   v[i] = temp[i];
           }
 
           // Find the answer
           let sum = 0;
           for (let i = 0; i < 10; i++)
               sum = (sum + v[i]) % mod;
           return sum;
       }
 
       // Driver Code
       let N = 2;
       document.write(knightCalling(N));
 
 // This code is contributed by Potta Lokesh
   </script>


 
 

Output

20






 

Time Complexity: O(N)
Auxiliary Space: O(1)

Efficient Approach: After seeing above approach we can think that this is good enough for this type of problem, but there is an more efficient approach. Above approach is valid till 1e6, sometimes 1e7. But we can’t do above approach if our n is 1e9. Basically, for every 1e9 constraint problem logN complexity is the solution. We can do the problem using Matrix Exponentiation . We can create our initial matrix based on the knight conditions. We can exclude 5 as it is of no use except for n=1 case.

First, create a 9 X 9 matrix where row is the keypad number and col is the numbers where we can reach from that row. To have this we set 1 in that particular cols only. The initial matrix looks as shown below.

0 0 0 0 1 1 0 0 0 
0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 1 0 1
0 0 0 0 1 0 0 1 0
1 0 0 1 0 0 0 0 1
1 1 0 0 0 0 1 0 0
0 0 1 0 0 1 0 0 0
0 1 0 1 0 0 0 0 0
0 0 1 0 1 0 0 0 0

For a change and to reduce the matrix size, we exclude the 5th number and consider numbers > 5 as number – 1. Like we consider 7 as 6, 8 as 7 and so on. As we saw in first approach that it is a linear transformation of numbers, we can apply this matrix exponentiation.

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// MOD
const static int MOD = 1e9 + 7;
 
// vector represents the knight jumps
// Remeber the numbers>5=numbers-1
// condition
const vector<vector<int> > mp{
    { 4, 5 },    { 5, 7 }, { 6, 8 }, { 4, 7 }, { 3, 8, 0 },
    { 0, 1, 6 }, { 2, 5 }, { 1, 3 }, { 2, 4 }
};
 
// A struct to simplify matrix multiplication
struct M {
    vector<vector<int> > a;
    M(int n) { a.resize(n, vector<int>(n, 0)); }
    M operator*(const M& other) const
    {
        int n = a.size();
        M product(n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    product.a[i][k]
                        = (product.a[i][k]
                           + a[i][j] * 1ll * other.a[j][k])
                          % MOD;
                }
            }
        }
        return product;
    }
};
 
// matrix exponentiation function
M matpow(M a, int n, int sze)
{
    M res(sze);
    for (int i = 0; i < sze; i++) {
        res.a[i][i] = 1;
    }
    while (n) {
        if (n & 1)
            res = res * a;
        a = a * a;
        n >>= 1;
    }
    return res;
}
 
// Function to find the total number of ways
int knightCalling(int n)
{
      // one edge case of having 5
    if (n == 1)
        return 10;
   
      // initialize a matrix
      // set 1's as the knight conditions.
    M mat(9);
    for (int i = 0; i < 9; i++) {
        for (int k : mp[i]) {
            mat.a[i][k] = 1;
        }
    }
      // generate the resultant matrix
      // by matrix exponentiation
    M res = matpow(mat, n - 1, 9);
   
    int ans = 0;
      // Sum of all elements is the answer
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            ans = (ans * 1ll + res.a[i][j]) % MOD;
        }
    }
    return ans;
}
 
// Driver Code
int main()
{
    int N = 2;
    cout << knightCalling(N) << endl;
 
    int N1 = 3;
    cout << knightCalling(N1);
}


Java




import java.util.Arrays;
 
// A class to represent matrix for matrix exponentiation
class M {
    int[][] a;
 
    M(int n) {
        a = new int[n][n];
    }
 
    M multiply(M other, int mod) {
        int n = a.length;
        M product = new M(n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    product.a[i][k] = (int) ((product.a[i][k] + (long) a[i][j] * other.a[j][k]) % mod);
                }
            }
        }
        return product;
    }
 
    static M identity(int n) {
        M res = new M(n);
        for (int i = 0; i < n; i++) {
            res.a[i][i] = 1;
        }
        return res;
    }
}
 
public class KnightCalling {
 
    // MOD
    private static final int MOD = 1000000007;
 
    // vector represents the knight jumps
    // Remeber the numbers>5=numbers-1 condition
    private static final int[][] mp = {
            {4, 5}, {5, 7}, {6, 8}, {4, 7}, {3, 8, 0},
            {0, 1, 6}, {2, 5}, {1, 3}, {2, 4}
    };
 
    // matrix exponentiation function
    private static M matpow(M a, int n, int sze) {
        M res = M.identity(sze);
        while (n > 0) {
            if ((n & 1) == 1) {
                res = res.multiply(a, MOD);
            }
            a = a.multiply(a, MOD);
            n >>= 1;
        }
        return res;
    }
 
    // Function to find the total number of ways
    private static int knightCalling(int n) {
        // one edge case of having 5
        if (n == 1) {
            return 10;
        }
 
        // initialize a matrix
        // set 1's as the knight conditions.
        M mat = new M(9);
        for (int i = 0; i < 9; i++) {
            for (int k : mp[i]) {
                mat.a[i][k] = 1;
            }
        }
 
        // generate the resultant matrix
        // by matrix exponentiation
        M res = matpow(mat, n - 1, 9);
 
        int ans = 0;
        // Sum of all elements is the answer
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                ans = (int) ((ans + (long) res.a[i][j]) % MOD);
            }
        }
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args) {
        int N = 2;
        System.out.println(knightCalling(N));
 
        int N1 = 3;
        System.out.println(knightCalling(N1));
    }
}


Python




MOD = 10**9 + 7
 
# Vector represents the knight jumps
# Remember the numbers > 5 = numbers - 1 condition
mp = [
    [4, 5], [5, 7], [6, 8], [4, 7], [3, 8, 0],
    [0, 1, 6], [2, 5], [1, 3], [2, 4]
]
 
# A class to simplify matrix multiplication
 
 
class Matrix:
    def __init__(self, n):
        self.a = [[0] * n for _ in range(n)]
 
    def __mul__(self, other):
        n = len(self.a)
        product = Matrix(n)
        for i in range(n):
            for j in range(n):
                for k in range(n):
                    product.a[i][k] = (product.a[i][k] +
                                       self.a[i][j] * other.a[j][k]) % MOD
        return product
 
# Matrix exponentiation function
 
 
def matpow(a, n, sze):
    res = Matrix(sze)
    for i in range(sze):
        res.a[i][i] = 1
    while n:
        if n & 1:
            res = res * a
        a = a * a
        n >>= 1
    return res
 
# Function to find the total number of ways
 
 
def knightCalling(n):
    # One edge case of having 5
    if n == 1:
        return 10
 
    # Initialize a matrix, set 1's as the knight conditions
    mat = Matrix(9)
    for i in range(9):
        for k in mp[i]:
            mat.a[i][k] = 1
 
    # Generate the resultant matrix by matrix exponentiation
    res = matpow(mat, n - 1, 9)
 
    ans = 0
    # Sum of all elements is the answer
    for i in range(9):
        for j in range(9):
            ans = (ans + res.a[i][j]) % MOD
    return ans
 
 
# Driver Code
N = 2
print(knightCalling(N))
 
N1 = 3
print(knightCalling(N1))


C#




using System;
 
class Program
{
    // MOD
    private readonly static int MOD = 1000000007;
 
    // Vector represents the knight jumps
    // Remember the numbers > 5 = numbers - 1 condition
    private static readonly int[][] Mp =
    {
        new[] {4, 5},    new[] {5, 7}, new[] {6, 8}, new[] {4, 7}, new[] {3, 8, 0},
        new[] {0, 1, 6}, new[] {2, 5}, new[] {1, 3}, new[] {2, 4}
    };
 
    // A class to simplify matrix multiplication
    private class Matrix
    {
        public int[][] A;
 
        public Matrix(int n)
        {
            A = new int[n][];
            for (int i = 0; i < n; i++)
            {
                A[i] = new int[n];
            }
        }
 
        public static Matrix operator *(Matrix a, Matrix other)
        {
            int n = a.A.Length;
            var product = new Matrix(n);
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    for (int k = 0; k < n; k++)
                    {
                        product.A[i][k] = (int)((product.A[i][k] +
                                                 (long)a.A[i][j] * other.A[j][k]) % MOD);
                    }
                }
            }
            return product;
        }
    }
 
    // Matrix exponentiation function
    private static Matrix MatPow(Matrix a, int num, int size)
    {
        var res = new Matrix(size);
        for (int i = 0; i < size; i++)
        {
            res.A[i][i] = 1;
        }
        while (num > 0)
        {
            if ((num & 1) != 0)
                res = res * a;
            a = a * a;
            num >>= 1;
        }
        return res;
    }
 
    // Function to find the total number of ways
    private static int KnightCalling(int n)
    {
        // One edge case of having 5
        if (n == 1)
            return 10;
 
        // Initialize a matrix
        // Set 1's as the knight conditions.
        var mat = new Matrix(9);
        for (int i = 0; i < 9; i++)
        {
            foreach (int k in Mp[i])
            {
                mat.A[i][k] = 1;
            }
        }
 
        // Generate the resultant matrix
        // by matrix exponentiation
        var res = MatPow(mat, n - 1, 9);
 
        int ans = 0;
        // Sum of all elements is the answer
        for (int i = 0; i < 9; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                ans = (int)((ans + res.A[i][j]) % MOD);
            }
        }
        return ans;
    }
 
    // Driver Code
    static void Main()
    {
        int N = 2;
        Console.WriteLine(KnightCalling(N));
 
        int N1 = 3;
        Console.WriteLine(KnightCalling(N1));
    }
}


Javascript




// Modular constant for calculations
const MOD = 10**9 + 7;
 
// Array representing the knight's possible moves
const mp = [
    [4, 5], [5, 7], [6, 8], [4, 7], [3, 8, 0],
    [0, 1, 6], [2, 5], [1, 3], [2, 4]
];
 
// Class to simplify matrix multiplication
class Matrix {
    constructor(n) {
        this.a = Array.from({ length: n }, () => Array(n).fill(0));
    }
 
    multiply(other) {
        const n = this.a.length;
        const product = new Matrix(n);
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                for (let k = 0; k < n; k++) {
                    product.a[i][k] = (product.a[i][k] + this.a[i][j] * other.a[j][k]) % MOD;
                }
            }
        }
        return product;
    }
}
 
// Matrix exponentiation function
function matpow(a, n, sze) {
    let res = new Matrix(sze);
    for (let i = 0; i < sze; i++) {
        res.a[i][i] = 1;
    }
    while (n) {
        if (n & 1) {
            res = res.multiply(a);
        }
        a = a.multiply(a);
        n >>= 1;
    }
    return res;
}
 
// Function to find the total number of ways
function knightCalling(n) {
    // Handle the base case
    if (n === 1) {
        return 10;
    }
 
    // Initialize a matrix representing the knight's moves
    const mat = new Matrix(9);
    for (let i = 0; i < 9; i++) {
        for (let k of mp[i]) {
            mat.a[i][k] = 1;
        }
    }
 
    // Calculate the result by matrix exponentiation
    const res = matpow(mat, n - 1, 9);
 
    let ans = 0;
    // Sum all elements in the resulting matrix
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            ans = (ans + res.a[i][j]) % MOD;
        }
    }
    return ans;
}
 
// Example usage
const N = 2;
console.log(knightCalling(N));
 
const N1 = 3;
console.log(knightCalling(N1));


Output

20
46

Time Complexity: O(log(N))

Space Complexity: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads