// Function to generate the next possible mask based on the current mask and position
function generateNextMask(n, curr_mask, new_mask, j, nextMask) {
if (j === n) {
nextMask.push(new_mask);
return;
}
// If there's enough space and cells are empty, place a 2x1 tile
if (j + 1 < n && (((1 << j) & curr_mask) === 0) && (((1 << (j + 1)) & curr_mask) === 0)) {
generateNextMask(n, curr_mask, new_mask, j + 2, nextMask);
}
// Place a 1x2 tile if the cell is empty
if (((1 << j) & curr_mask) === 0) {
generateNextMask(n, curr_mask, new_mask + (1 << j), j + 1, nextMask);
}
// Move to the next cell if the current cell is already filled
if (((1 << j) & curr_mask) !== 0) {
generateNextMask(n, curr_mask, new_mask, j + 1, nextMask);
}
}
// Recursive function to compute the number of ways to fill the grid
function countWays(n, m, i, mask, dp) {
// Base case: reached the end of the grid
if (i === m) {
// If the entire grid is filled, return 1, otherwise return 0
if (mask === 0)
return 1;
else
return 0;
}
const MOD = 1e9 + 7; // Define MOD constant
// If the result for the current state is already computed, return it
if (dp[i][mask] !== -1)
return dp[i][mask];
// Generate next possible masks for the current column
let nextMask = [];
generateNextMask(n, mask, 0, 0, nextMask);
// Initialize the answer for the current state
let ans = 0;
// Iterate over all possible next masks and recursively compute the answer
for (let x of nextMask) {
ans = (ans % MOD + countWays(n, m, i + 1, x, dp) % MOD) % MOD;
}
// Memoize the result and return it
dp[i][mask] = ans;
return dp[i][mask];
}
// Driver Code
function main() {
const n = 2, m = 2;
// Initialize dp array with -1
let dp = new Array(m).fill(null).map(() => new Array(1 << n).fill(-1));
// Compute and print the number of ways to fill the grid
console.log(countWays(n, m, 0, 0, dp));
}
main();