Open In App

Count of Possible paths of given Matrix having Bitwise XOR equal to K

Last Updated : 28 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an N*M (N + M ≤ 40)matrix mat[][], each cell has some value ranging from 0 to 1018 and an integer  K. Find the count of all possible paths such that bitwise XOR of elements in a path is equal to K. Movement is allowed only in the right and downward direction. 

Examples:

Input: N = 3, M = 4, K= 2
mat[][] = { {1, 3, 3, 3},
                 {0, 3, 3, 2},
                 {3, 0, 1, 1} }
Output: 5
Explanation: All possible paths are: 
(1,1)→(2,1)→(2,2)→(3,2)→(3,3)→(3,4) =  1^0 ^3^0^1^1 = 2
(1,1)→(2,1)→(3,1)→(3,2)→(3,3)→(3,4) = 1^0^3^0^1^1 = 2
(1,1)→(2,1)→(2,2)→(2,3)→(2,4)→(3,4) = 1^0^3^3^2^1 =2
(1,1)→(1,2)→(1,3)→(2,3)→(3,3)→(3,4) = 1^3^3^3^1^1 =2
(1,1)→(1,2)→(2,2)→(2,3)→(3,3)→(3,4) =  1^3^3^3^1^1 =2

Input: N = 3, M = 3, K =11
 mat[][] = { {2, 1, 5},
                  {7, 10, 0},
                  {12, 6, 4} }
Output: 3
Explanation:All possible paths are: 
(1,1)→(2,1)→(3,1)→(3,2)→(3,3) = 2 ^ 7 ^12 ^ 6 ^4 =11
(1,1)→(2,1)→(2,2)→(2,3)→(3,3) = 2 ^ 7 ^ 10 ^ 0 ^4 =11
(1,1)→(1,2)→(2,2)→(3,2)→(3,3) = 2^1^10^ 6 ^ 4 = 11 

 

Naive Approach: The simple approach is to travel all possible paths and check if the XOR of that path is equal to K or not. In this, use backtracking as at any given cell there will be two choices either to go right or down and this would become two recursive statements in backtracking solution.

Below is the implementation of the above approach :

C++




// C++ code to implement the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long int
ll n, m, k;
vector<vector<ll>> mat;
 
// Backtracking to find the path count
void backtracking(ll i, ll j, ll zor, ll &ans)
{
    // If the bottom-right cell is reached
    if (i == n - 1 && j == m - 1) {
         
        // If XOR value is k
        if (zor == k)
            ans++;
        return;
    }
 
    // Move rightwards
    if (j + 1 < m)
        backtracking(i, j + 1,
                     zor ^ mat[i][j + 1],
                     ans);
   
    // Move downwards
    if (i + 1 < n)
        backtracking(i + 1, j,
                     zor ^ mat[i + 1][j],
                     ans);
}
 
// Function to calculate all possible paths
int countPaths(int N, int M, int K)
{
    ll ans = 0;
    n = N; m = M; k = K;
    if (N == 1 && M == 1
        && mat[0][0] == K) {
        return 1;
    }
   
    // Calling the backtracking function
    backtracking(0, 0, mat[0][0], ans);
    return ans;
}
 
// Driver Code
int main()
{
    int N = 3, M = 3, K = 11;
    mat = { {2, 1, 5}, {7, 10, 0},
            {12, 6, 4} };
 
    // Function call
    int ans = countPaths(N, M, K);
    cout << ans << "\n";
    return 0;
}


Java




// Java code to implement the above approach
import java.util.*;
 
class GFG{
 
  static int  n, m, k , ans;
  static int [][]mat;
 
  // Backtracking to find the path count
  static void backtracking(int i, int j, int zor)
  {
    // If the bottom-right ceint is reached
    if (i == n - 1 && j == m - 1) {
 
      // If XOR value is k
      if (zor == k)
        ans++;
      return;
    }
 
    // Move rightwards
    if (j + 1 < m)
      backtracking(i, j + 1,
                   zor ^ mat[i][j + 1]);
 
    // Move downwards
    if (i + 1 < n)
      backtracking(i + 1, j,
                   zor ^ mat[i + 1][j]);
  }
 
  // Function to calculate all possible paths
  static int countPaths(int N, int M, int K)
  {
    ans = 0;
    n = N; m = M; k = K;
    if (N == 1 && M == 1
        && mat[0][0] == K) {
      return 1;
    }
 
    // Calling the backtracking function
    backtracking(0, 0, mat[0][0]);
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int N = 3, M = 3, K = 11;
    mat = new int[][]{ {2, 1, 5}, {7, 10, 0},
                      {12, 6, 4} };
 
    // Function call
    int ans = countPaths(N, M, K);
    System.out.print(ans+ "\n");
  }
}
 
// This code is contributed by 29AjayKumar


Python3




# Python program to find maximum sum in Binary Tree
mat = [[0 for i in range(2)]for j in range(2)]
n,m,k,ans = 0,0,0,0
 
# Backtracking to find the path count
def backtracking(i, j, zor):
 
    global ans
 
    # If the bottom-right ceis reached
    if (i == n - 1 and j == m - 1):
 
        # If XOR value is k
        if (zor == k):
            ans += 1
        return
 
    # Move rightwards
    if (j + 1 < m):
        backtracking(i, j + 1,zor ^ mat[i][j + 1])
 
    # Move downwards
    if (i + 1 < n):
        backtracking(i + 1, j,zor ^ mat[i + 1][j])
 
# Function to calculate all possible paths
def countPaths(N, M, K):
 
    global n,m,k,ans
 
    ans = 0
    n,m,k = N,M,K
    if (N == 1 and M == 1 and mat[0][0] == K):
        return 1
 
    # Calling the backtracking function
    backtracking(0, 0, mat[0][0])
    return ans
 
 
# Driver Code
N,M,K = 3,3,11
mat = [ [2, 1, 5], [7, 10, 0],
                    [12, 6, 4]]
 
# Function call
anss = countPaths(N, M, K)
print(anss)
 
# This code is contributed by shinjanpatra


C#




// C# code to implement the above approach
using System;
 
class GFG{
 
  static int  n, m, k, ans;
 
  // Backtracking to find the path count
  static void backtracking(int i, int j, int zor, int [,]mat)
  {
    // If the bottom-right ceint is reached
    if (i == n - 1 && j == m - 1) {
 
      // If XOR value is k
      if (zor == k)
        ans++;
      return;
    }
 
    // Move rightwards
    if (j + 1 < m)
      backtracking(i, j + 1,
                   zor ^ mat[i, j + 1], mat);
 
    // Move downwards
    if (i + 1 < n)
      backtracking(i + 1, j,
                   zor ^ mat[i + 1, j], mat);
  }
 
  // Function to calculate all possible paths
  static int countPaths(int N, int M, int K, int [,]mat)
  {
    ans = 0;
    n = N; m = M; k = K;
    if (N == 1 && M == 1
        && mat[0, 0] == K) {
      return 1;
    }
 
    // Calling the backtracking function
    backtracking(0, 0, mat[0, 0], mat);
    return ans;
  }
 
  // Driver Code
  public static void Main()
  {
    int N = 3, M = 3, K = 11;
    int [,]mat = { {2, 1, 5}, {7, 10, 0},
                      {12, 6, 4} };
 
    // Function call
    int ans = countPaths(N, M, K, mat);
    Console.Write(ans+ "\n");
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
    // JavaScript program to implement above approach
 
  let  n, m, k , ans;
 var mat = new Array(2);
  
// Loop to create 2D array using 1D array
for (var i = 0; i < mat.length; i++) {
    mat[i] = new Array(2);
}
 
  // Backtracking to find the path count
  function backtracking(i, j, zor)
  {
    // If the bottom-right celet is reached
    if (i == n - 1 && j == m - 1) {
 
      // If XOR value is k
      if (zor == k)
        ans++;
      return;
    }
 
    // Move rightwards
    if (j + 1 < m)
      backtracking(i, j + 1,
                   zor ^ mat[i][j + 1]);
 
    // Move downwards
    if (i + 1 < n)
      backtracking(i + 1, j,
                   zor ^ mat[i + 1][j]);
  }
 
  // Function to calculate all possible paths
  function countPaths(N, M, K)
  {
    ans = 0;
    n = N; m = M; k = K;
    if (N == 1 && M == 1
        && mat[0][0] == K) {
      return 1;
    }
 
    // Calling the backtracking function
    backtracking(0, 0, mat[0][0]);
    return ans;
  }
 
    // Driver Code
    let N = 3, M = 3, K = 11;
    mat = [ [2, 1, 5], [7, 10, 0],
                      [12, 6, 4]];
 
    // Function call
    let anss = countPaths(N, M, K);
    document.write(anss);
 
// This code iscontributed by sanjoy_62.
</script>


Output

3




Time Complexity: O(2X * X) where X = (N + M – 2)
Auxiliary Space: O(1)

Why simply  Backtracking would fail here?
The number of moves required to move from (1, 1) to (N, M) will be equal to (N+M-2). Now, using a recursive backtracking solution It will take O(2(N+M-2)) time to iterate over all the paths of this length and check if each path is having XOR equal to K or not. For higher values of (N+M) this algorithm becomes very time consuming as the value reaches close to the constraint provided here.

Efficient Approach: Using Meet in The Middle Algorithm split the number of steps and make (N + M – 2)/2 in the first half, rest steps in the next half. Follow the steps mentioned below to solve the problem:

  • And combine the answers of the two solutions, which is basically the standard idea of the Meet in the Middle Algorithm.
  • Split this mask of n+m−2 bits into two parts, mid=(n+m−2)/2 bits and (n+m−2)−mid bits.
  • For The Left Part: 
    • Perform recursive backtracking starting from the cell (1,1) and to the bottom and maintain xor of the path for mid steps. after mid steps, we have the index position i.e. (i,j) and the xor value up to this point, and calculate how many such triplets exits {zor, i,j}
  • For The Right Part: 
    • Perform recursive backtracking starting from the cell (N, M) and to the left or to the upwards and maintain xor of the path for
       (N+M-2) – mid -1 steps.
  • after mid steps in, the index position i.e. (i,j) is found and the xor value up to this point, and calculate how many such triplets exits {zor, i,j}
  • After writing code for both parts now traverse the triplets of the second part and check if in one step i.e (i-1,j) or (j-1, i) we have a triplet having xor K in triplets of the left part.

Below is the implementation of the above approach:

C++14




// C++ code to implement the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long int
ll n, m, k;
vector<vector<ll>> a;
ll cnt1 = 0, cnt2 = 0;
map<pair<ll, pair<ll, ll> >, ll> mp1, mp2;
 
// Backtracking function for the left part
void part1(ll i, ll j, ll cnt, ll zor)
{
    if (cnt <= 0) {
         
        // Count the number of triplets
        mp1[{ zor, { i, j } }]++;
        return;
    }
 
    // Move rightwards
    if (j + 1 < m) {
        part1(i, j + 1, cnt - 1,
              zor ^ a[i][j + 1]);
    }
   
    // Move downwards
    if (i + 1 < n)
        part1(i + 1, j, cnt - 1,
              zor ^ a[i + 1][j]);
}
 
// Backtracking function for the right part
void part2(ll i, ll j, ll cnt, ll zor)
{
    if (cnt <= 0) {
         
        // Count the number of triplets
        mp2[{ zor, { i, j } }]++;
        return;
    }
 
    // Move leftwards
    if (j - 1 >= 0) {
        part2(i, j - 1, cnt - 1,
              zor ^ a[i][j - 1]);
    }
   
    // Move upwards
    if (i - 1 >= 0)
        part2(i - 1, j, cnt - 1,
              zor ^ a[i - 1][j]);
}
 
// Function to count the paths with xor K
int countPaths(int N, int M, int K)
{
    ll ans = 0;
    n = N; m = M; k = K;
     
    // Number of steps for left part
    cnt1 = (n + m - 2) / 2;
 
    // NUmber of steps for right part
    cnt2 = (n + m - 2) - cnt1;
 
    // number of steps in both parts are 0
    if (n == 1 && m == 1 && a[0][0] == k) {
        return 1;
    }
 
    // Calling the recursive function
    // for the left and right part
    part1(0, 0, cnt1, a[0][0]);
    part2(n - 1, m - 1, cnt2 - 1,
          a[n - 1][m - 1]);
 
    // mp2 contains triplet of right part so
    // traverse the triplets of right part
    for (auto i : mp2) {
 
        // Extracting all elements
        // from the triplet
        ll zor = i.first.first;
        ll idx = i.first.second.first;
        ll j = i.first.second.second;
        ll cnt = i.second;
 
        // XOR OF RIGHT SIDE IS zor ,
        // then Xor of left side
        // must be zor^k such that Xor
        // of the total path is K
        ll required = k ^ zor;
 
        // Checking if one index to the left
        // are left triplet as how many paths
        if ((idx - 1) >= 0
            && mp1.find({ required,
                         { idx - 1, j } })
                   != mp1.end()) {
 
            // Total path would be paths
            // in left * paths in right
            ans += (cnt
                    * mp1[{ required,
                           { idx - 1, j } }]);
        }
 
        // Checking if one index upwards
        // are left triplet as how many paths
        if ((j - 1) >= 0
            && mp1.find({ required,
                         { idx, j - 1 } })
                   != mp1.end()) {
             
            // Total path would be paths
            // in left * paths in right
            ans += (cnt
                    * mp1[{ required,
                           { idx, j - 1 } }]);
        }
    }
    return ans;
}
 
// Driver Code
int main()
{
    int N = 3, M = 3, K = 11;
    a = { {2, 1, 5}, {7, 10, 0},
            {12, 6, 4} };
     
    int ans = countPaths(N, M, K);
    cout << ans;
    return 0;
}


Java




import java.util.HashMap;
import java.util.Map;
 
public class PathCount {
    static int cnt1, cnt2;
    static Map<String, Integer> mp1 = new HashMap<>();
    static Map<String, Integer> mp2 = new HashMap<>();
    static int[][] a;
    static int n, m, k;
 
    // Backtracking function for the left part
    static void part1(int i, int j, int cnt, int zor) {
        if (cnt <= 0) {
            // Count the number of triplets
            String key = zor + "," + i + "," + j;
            mp1.put(key, mp1.getOrDefault(key, 0) + 1);
            return;
        }
 
        // Move rightwards
        if (j + 1 < m) {
            part1(i, j + 1, cnt - 1, zor ^ a[i][j + 1]);
        }
 
        // Move downwards
        if (i + 1 < n) {
            part1(i + 1, j, cnt - 1, zor ^ a[i + 1][j]);
        }
    }
 
    // Backtracking function for the right part
    static void part2(int i, int j, int cnt, int zor) {
        if (cnt <= 0) {
            // Count the number of triplets
            String key = zor + "," + i + "," + j;
            mp2.put(key, mp2.getOrDefault(key, 0) + 1);
            return;
        }
 
        // Move leftwards
        if (j - 1 >= 0) {
            part2(i, j - 1, cnt - 1, zor ^ a[i][j - 1]);
        }
 
        // Move upwards
        if (i - 1 >= 0) {
            part2(i - 1, j, cnt - 1, zor ^ a[i - 1][j]);
        }
    }
 
    // Function to count the paths with xor K
    static int countPaths(int N, int M, int K) {
        int ans = 0;
        n = N;
        m = M;
        k = K;
 
        // Number of steps for left part
        cnt1 = (n + m - 2) / 2;
 
        // Number of steps for the right part
        cnt2 = (n + m - 2) - cnt1;
 
        // number of steps in both parts are 0
        if (n == 1 && m == 1 && a[0][0] == k) {
            return 1;
        }
 
        // Calling the recursive function for the left and right part
        part1(0, 0, cnt1, a[0][0]);
        part2(n - 1, m - 1, cnt2 - 1, a[n - 1][m - 1]);
 
        // mp2 contains triplets of the right part, so traverse the triplets of the right part
        for (String key : mp2.keySet()) {
            // Extracting all elements from the triplet
            String[] parts = key.split(",");
            int zor = Integer.parseInt(parts[0]);
            int idx = Integer.parseInt(parts[1]);
            int j = Integer.parseInt(parts[2]);
            int cnt = mp2.get(key);
 
            // XOR OF RIGHT SIDE IS zor,
            // then XOR of the left side
            // must be zor^k such that XOR
            // of the total path is K
            int required = k ^ zor;
 
            // Checking if one index to the left
            // are left triplets and how many paths
            String leftKey1 = required + "," + idx + "," + (j - 1);
            if (j - 1 >= 0 && mp1.containsKey(leftKey1)) {
                // Total path would be paths in left * paths in right
                ans += cnt * mp1.get(leftKey1);
            }
 
            // Checking if one index upwards
            // are left triplets and how many paths
            String leftKey2 = required + "," + (idx - 1) + "," + j;
            if (idx - 1 >= 0 && mp1.containsKey(leftKey2)) {
                // Total path would be paths in left * paths in right
                ans += cnt * mp1.get(leftKey2);
            }
        }
 
        return ans;
    }
 
    public static void main(String[] args) {
        n = 3;
        m = 3;
        k = 11;
        a = new int[][]{
                {2, 1, 5},
                {7, 10, 0},
                {12, 6, 4}
        };
 
        // Function call
        int ans = countPaths(n, m, k);
        System.out.println(ans);
    }
}


Python3




from typing import List, Tuple
from collections import defaultdict
 
def count_paths(n: int, m: int, k: int, a: List[List[int]]) -> int:
    # cnt1: number of steps in left part
    # cnt2: number of steps in right part
    cnt1 = (n + m - 2) // 2
    cnt2 = (n + m - 2) - cnt1
     
    # Edge case: matrix is 1x1 and the only element is k
    if n == 1 and m == 1 and a[0][0] == k:
        return 1
 
    mp1 = defaultdict(int) # left part
    mp2 = defaultdict(int) # right part
 
    # Recursive function for left part
    def part1(i: int, j: int, cnt: int, zor: int) -> None:
        if cnt <= 0:
            # Count the number of triplets
            mp1[(zor, (i, j))] += 1
            return
         
        # Move rightwards
        if j + 1 < m:
            part1(i, j + 1, cnt - 1, zor ^ a[i][j + 1])
             
        # Move downwards
        if i + 1 < n:
            part1(i + 1, j, cnt - 1, zor ^ a[i + 1][j])
 
    # Recursive function for right part
    def part2(i: int, j: int, cnt: int, zor: int) -> None:
        if cnt <= 0:
            # Count the number of triplets
            mp2[(zor, (i, j))] += 1
            return
         
        # Move leftwards
        if j - 1 >= 0:
            part2(i, j - 1, cnt - 1, zor ^ a[i][j - 1])
             
        # Move upwards
        if i - 1 >= 0:
            part2(i - 1, j, cnt - 1, zor ^ a[i - 1][j])
 
    # Call the recursive functions for left and right parts
    part1(0, 0, cnt1, a[0][0])
    part2(n - 1, m - 1, cnt2 - 1, a[n - 1][m - 1])
 
    ans = 0
    # Iterate through the triplets in the right part
    for zor, (idx, j), cnt in mp2.items():
        # XOR of right side is zor, XOR of left side must be zor^k
        # such that XOR of the total path is K
        required = k ^ zor
         
        # Check if there is a left triplet one index to the left
        if idx - 1 >= 0 and (required, (idx - 1, j)) in mp1:
            # Total path is paths in left * paths in right
            ans += cnt * mp1[(required, (idx - 1, j))]
         
        # Check if there is a left triplet one index upwards
        if j - 1 >= 0 and (required, (idx, j - 1)) in mp1:


C#




using System;
using System.Collections.Generic;
 
class MainClass
{
    // Using a Dictionary for mp1 and mp2 in C#
    static Dictionary<string, int> mp1 = new Dictionary<string, int>();
    static Dictionary<string, int> mp2 = new Dictionary<string, int>();
 
    // Backtracking function for the left part
    static void Part1(int i, int j, int cnt, int zor, int[][] a, int n, int m)
    {
        if (cnt <= 0)
        {
            // Count the number of triplets
            string key = $"{zor},{i},{j}";
            if (!mp1.ContainsKey(key)) mp1[key] = 0;
            mp1[key]++;
            return;
        }
 
        // Move rightwards
        if (j + 1 < m)
        {
            Part1(i, j + 1, cnt - 1, zor ^ a[i][j + 1], a, n, m);
        }
 
        // Move downwards
        if (i + 1 < n)
        {
            Part1(i + 1, j, cnt - 1, zor ^ a[i + 1][j], a, n, m);
        }
    }
 
    // Backtracking function for the right part
    static void Part2(int i, int j, int cnt, int zor, int[][] a, int n, int m)
    {
        if (cnt <= 0)
        {
            // Count the number of triplets
            string key = $"{zor},{i},{j}";
            if (!mp2.ContainsKey(key)) mp2[key] = 0;
            mp2[key]++;
            return;
        }
 
        // Move leftwards
        if (j - 1 >= 0)
        {
            Part2(i, j - 1, cnt - 1, zor ^ a[i][j - 1], a, n, m);
        }
 
        // Move upwards
        if (i - 1 >= 0)
        {
            Part2(i - 1, j, cnt - 1, zor ^ a[i - 1][j], a, n, m);
        }
    }
 
    // Function to count the paths with XOR K
    static int CountPaths(int N, int M, int K, int[][] a)
    {
        int ans = 0;
        int n = N;
        int m = M;
        int k = K;
 
        int cnt1 = (n + m - 2) / 2;
        int cnt2 = (n + m - 2) - cnt1;
 
        // Edge case: matrix is 1x1 and the only element is k
        if (n == 1 && m == 1 && a[0][0] == k)
        {
            return 1;
        }
 
        Part1(0, 0, cnt1, a[0][0], a, n, m);
        Part2(n - 1, m - 1, cnt2 - 1, a[n - 1][m - 1], a, n, m);
 
        foreach (var item in mp2)
        {
            var split = item.Key.Split(',');
            int zor = int.Parse(split[0]);
            int idx = int.Parse(split[1]);
            int j = int.Parse(split[2]);
            int cnt = item.Value;
 
            int required = k ^ zor;
 
            if ((idx - 1) >= 0 && mp1.ContainsKey($"{required},{idx - 1},{j}"))
            {
                ans += cnt * mp1[$"{required},{idx - 1},{j}"];
            }
 
            if ((j - 1) >= 0 && mp1.ContainsKey($"{required},{idx},{j - 1}"))
            {
                ans += cnt * mp1[$"{required},{idx},{j - 1}"];
            }
        }
 
        return ans;
    }
 
    public static void Main(string[] args)
    {
        int[][] a = new int[3][]
        {
            new int[] { 2, 1, 5 },
            new int[] { 7, 10, 0 },
            new int[] { 12, 6, 4 }
        };
 
        int ans = CountPaths(3, 3, 11, a);
        Console.WriteLine(ans); // Output: 3
    }
}


Javascript




// JavaScript code for the approach
 
let cnt1 = 0, cnt2 = 0;
let mp1 = {}, mp2 = {};
 
// Backtracking function for the left part
function part1(i, j, cnt, zor) {
  if (cnt <= 0) {
    // Count the number of triplets
    mp1[`${zor},${i},${j}`] = (mp1[`${zor},${i},${j}`] || 0) + 1;
    return;
  }
 
  // Move rightwards
  if (j + 1 < m) {
    part1(i, j + 1, cnt - 1, zor ^ a[i][j + 1]);
  }
     
  // Move downwards
  if (i + 1 < n) {
    part1(i + 1, j, cnt - 1, zor ^ a[i + 1][j]);
  }
}
 
// Backtracking function for the right part
function part2(i, j, cnt, zor) {
  if (cnt <= 0) {
    // Count the number of triplets
    mp2[`${zor},${i},${j}`] = (mp2[`${zor},${i},${j}`] || 0) + 1;
    return;
  }
 
  // Move leftwards
  if (j - 1 >= 0) {
    part2(i, j - 1, cnt - 1, zor ^ a[i][j - 1]);
  }
   
  // Move upwards
  if (i - 1 >= 0) {
    part2(i - 1, j, cnt - 1, zor ^ a[i - 1][j]);
  }
}
 
// Function to count the paths with xor K
function countPaths(N, M, K) {
  let ans = 0;
  n = N; m = M; k = K;
   
  // Number of steps for left part
  cnt1 = (n + m - 2) / 2;
   
  // Number of steps for right part
  cnt2 = (n + m - 2) - cnt1;
 
  // number of steps in both parts are 0
  if (n == 1 && m == 1 && a[0][0] == k) {
    return 1;
  }
 
  // Calling the recursive function
  // for the left and right part
  part1(0, 0, cnt1, a[0][0]);
  part2(n - 1, m - 1, cnt2 - 1, a[n - 1][m - 1]);
 
  // mp2 contains triplet of right part so
  // traverse the triplets of right part
  for (let i in mp2) {
    // Extracting all elements
    // from the triplet
    let [zor, idx, j] = i.split(',').map(Number);
    let cnt = mp2[i];
     
    // XOR OF RIGHT SIDE IS zor ,
    // then Xor of left side
    // must be zor^k such that Xor
    // of the total path is K
    let required = k ^ zor;
     
    // Checking if one index to the left
    // are left triplet as how many paths
    if ((idx - 1) >= 0 && mp1[`${required},${idx - 1},${j}`] !== undefined) {
      // Total path would be paths
      // in left * paths in right
      ans += cnt * mp1[`${required},${idx - 1},${j}`];
    }
 
    // Checking if one index upwards
    // are left triplet as how many paths
    if ((j - 1) >= 0 && mp1[`${required},${idx},${j - 1}`] !== undefined) {
      // Total path would be paths
      // in left * paths in right
      ans += cnt * mp1[`${required},${idx},${j - 1}`];
    }
  }
 
  return ans;
}
 
// Driver's code
let n, m, k;
let a = [
  [2, 1, 5],
  [7, 10, 0],
  [12, 6, 4]
];
 
// Function call
let ans = countPaths(3, 3, 11);
console.log(ans);


Output

3




 Time Complexity: O(X * 2X) where X = (N + M – 2)/2
Auxiliary Space: O(N + M)  



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

Similar Reads