Below is the implementation of the painting a grid:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192/** * Count the number of ways to paint an m × n grid with three colors. * * @param {number} m - Number of rows * @param {number} n - Number of columns * @return {number} - Number of ways to paint the grid */function colorTheGrid(m, n) { const MOD = 1000000007; // Generate all valid column states const validStates = []; const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); } } // Precompute valid transitions const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; for (const state2 of validStates) { if (canTransition(state1, state2, m)) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (const state2 of validTransitions[state1]) { const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} /** * Check if a column state is valid (no adjacent cells have the same color). * * @param {number} state - The column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the state is valid, false otherwise */function isValidState(state, m) { // Convert state to base-3 representation const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } // Check if adjacent cells have different colors for (let i = 0; i < m - 1; i++) { if (colors[i] === colors[i + 1]) { return false; } } return true;} /** * Check if two column states can be adjacent (no horizontally adjacent cells have the same color). * * @param {number} state1 - The first column state in base-3 * @param {number} state2 - The second column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the states can be adjacent, false otherwise */function canTransition(state1, state2, m) { // Convert states to base-3 representation const colors1 = []; const colors2 = []; let tempState1 = state1; let tempState2 = state2; for (let i = 0; i < m; i++) { colors1.push(tempState1 % 3); colors2.push(tempState2 % 3); tempState1 = Math.floor(tempState1 / 3); tempState2 = Math.floor(tempState2 / 3); } // Check if horizontally adjacent cells have different colors for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { return false; } } return true;} // Optimized version for larger inputsfunction colorTheGridOptimized(m, n) { const MOD = 1000000007; // Generate all valid column states and their color configurations const validStates = []; const colorConfigs = new Map(); const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); // Store the color configuration for this state const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } colorConfigs.set(state, colors); } } // Precompute valid transitions using color configurations const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; const colors1 = colorConfigs.get(state1); for (const state2 of validStates) { const colors2 = colorConfigs.get(state2); let valid = true; for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { valid = false; break; } } if (valid) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (let k = 0; k < validTransitions[state1].length; k++) { const state2 = validTransitions[state1][k]; const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} // Test casesconsole.log(colorTheGrid(1, 1)); // 3console.log(colorTheGrid(1, 2)); // 6console.log(colorTheGrid(5, 3)); // 580986
Let's break down the implementation:
Implement the painting a grid solution in different programming languages.
Below is the implementation of the painting a grid in different programming languages. Select a language tab to view the corresponding code.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192/** * Count the number of ways to paint an m × n grid with three colors. * * @param {number} m - Number of rows * @param {number} n - Number of columns * @return {number} - Number of ways to paint the grid */function colorTheGrid(m, n) { const MOD = 1000000007; // Generate all valid column states const validStates = []; const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); } } // Precompute valid transitions const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; for (const state2 of validStates) { if (canTransition(state1, state2, m)) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (const state2 of validTransitions[state1]) { const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} /** * Check if a column state is valid (no adjacent cells have the same color). * * @param {number} state - The column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the state is valid, false otherwise */function isValidState(state, m) { // Convert state to base-3 representation const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } // Check if adjacent cells have different colors for (let i = 0; i < m - 1; i++) { if (colors[i] === colors[i + 1]) { return false; } } return true;} /** * Check if two column states can be adjacent (no horizontally adjacent cells have the same color). * * @param {number} state1 - The first column state in base-3 * @param {number} state2 - The second column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the states can be adjacent, false otherwise */function canTransition(state1, state2, m) { // Convert states to base-3 representation const colors1 = []; const colors2 = []; let tempState1 = state1; let tempState2 = state2; for (let i = 0; i < m; i++) { colors1.push(tempState1 % 3); colors2.push(tempState2 % 3); tempState1 = Math.floor(tempState1 / 3); tempState2 = Math.floor(tempState2 / 3); } // Check if horizontally adjacent cells have different colors for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { return false; } } return true;} // Optimized version for larger inputsfunction colorTheGridOptimized(m, n) { const MOD = 1000000007; // Generate all valid column states and their color configurations const validStates = []; const colorConfigs = new Map(); const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); // Store the color configuration for this state const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } colorConfigs.set(state, colors); } } // Precompute valid transitions using color configurations const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; const colors1 = colorConfigs.get(state1); for (const state2 of validStates) { const colors2 = colorConfigs.get(state2); let valid = true; for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { valid = false; break; } } if (valid) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (let k = 0; k < validTransitions[state1].length; k++) { const state2 = validTransitions[state1][k]; const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} // Test casesconsole.log(colorTheGrid(1, 1)); // 3console.log(colorTheGrid(1, 2)); // 6console.log(colorTheGrid(5, 3)); // 580986
First, understand that we need to count the number of ways to paint an m × n grid with three colors such that no adjacent cells have the same color.
Generate all valid column states where no adjacent cells in the column have the same color.
For each valid column state, precompute all valid next states that can follow it (no horizontally adjacent cells have the same color).
Use dynamic programming to count the number of ways to paint the grid, considering one column at a time.
Optimize the space complexity by only storing the DP results for the current column.
Modify the code to implement an alternative approach and test it with the same examples.
Implement a function that solves the painting a grid problem using a different approach than shown above.
Handle the case where the grid is 1×1 (can be painted in 3 ways).
Handle the case where the grid has only one row (alternating colors).
Handle the case where the grid has only one column (alternating colors).
Below is the implementation of the painting a grid:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192/** * Count the number of ways to paint an m × n grid with three colors. * * @param {number} m - Number of rows * @param {number} n - Number of columns * @return {number} - Number of ways to paint the grid */function colorTheGrid(m, n) { const MOD = 1000000007; // Generate all valid column states const validStates = []; const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); } } // Precompute valid transitions const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; for (const state2 of validStates) { if (canTransition(state1, state2, m)) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (const state2 of validTransitions[state1]) { const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} /** * Check if a column state is valid (no adjacent cells have the same color). * * @param {number} state - The column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the state is valid, false otherwise */function isValidState(state, m) { // Convert state to base-3 representation const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } // Check if adjacent cells have different colors for (let i = 0; i < m - 1; i++) { if (colors[i] === colors[i + 1]) { return false; } } return true;} /** * Check if two column states can be adjacent (no horizontally adjacent cells have the same color). * * @param {number} state1 - The first column state in base-3 * @param {number} state2 - The second column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the states can be adjacent, false otherwise */function canTransition(state1, state2, m) { // Convert states to base-3 representation const colors1 = []; const colors2 = []; let tempState1 = state1; let tempState2 = state2; for (let i = 0; i < m; i++) { colors1.push(tempState1 % 3); colors2.push(tempState2 % 3); tempState1 = Math.floor(tempState1 / 3); tempState2 = Math.floor(tempState2 / 3); } // Check if horizontally adjacent cells have different colors for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { return false; } } return true;} // Optimized version for larger inputsfunction colorTheGridOptimized(m, n) { const MOD = 1000000007; // Generate all valid column states and their color configurations const validStates = []; const colorConfigs = new Map(); const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); // Store the color configuration for this state const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } colorConfigs.set(state, colors); } } // Precompute valid transitions using color configurations const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; const colors1 = colorConfigs.get(state1); for (const state2 of validStates) { const colors2 = colorConfigs.get(state2); let valid = true; for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { valid = false; break; } } if (valid) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (let k = 0; k < validTransitions[state1].length; k++) { const state2 = validTransitions[state1][k]; const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} // Test casesconsole.log(colorTheGrid(1, 1)); // 3console.log(colorTheGrid(1, 2)); // 6console.log(colorTheGrid(5, 3)); // 580986
Let's break down the implementation:
Implement the painting a grid solution in different programming languages.
Below is the implementation of the painting a grid in different programming languages. Select a language tab to view the corresponding code.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192/** * Count the number of ways to paint an m × n grid with three colors. * * @param {number} m - Number of rows * @param {number} n - Number of columns * @return {number} - Number of ways to paint the grid */function colorTheGrid(m, n) { const MOD = 1000000007; // Generate all valid column states const validStates = []; const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); } } // Precompute valid transitions const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; for (const state2 of validStates) { if (canTransition(state1, state2, m)) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (const state2 of validTransitions[state1]) { const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} /** * Check if a column state is valid (no adjacent cells have the same color). * * @param {number} state - The column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the state is valid, false otherwise */function isValidState(state, m) { // Convert state to base-3 representation const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } // Check if adjacent cells have different colors for (let i = 0; i < m - 1; i++) { if (colors[i] === colors[i + 1]) { return false; } } return true;} /** * Check if two column states can be adjacent (no horizontally adjacent cells have the same color). * * @param {number} state1 - The first column state in base-3 * @param {number} state2 - The second column state in base-3 * @param {number} m - Number of rows * @return {boolean} - True if the states can be adjacent, false otherwise */function canTransition(state1, state2, m) { // Convert states to base-3 representation const colors1 = []; const colors2 = []; let tempState1 = state1; let tempState2 = state2; for (let i = 0; i < m; i++) { colors1.push(tempState1 % 3); colors2.push(tempState2 % 3); tempState1 = Math.floor(tempState1 / 3); tempState2 = Math.floor(tempState2 / 3); } // Check if horizontally adjacent cells have different colors for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { return false; } } return true;} // Optimized version for larger inputsfunction colorTheGridOptimized(m, n) { const MOD = 1000000007; // Generate all valid column states and their color configurations const validStates = []; const colorConfigs = new Map(); const limit = Math.pow(3, m); for (let state = 0; state < limit; state++) { if (isValidState(state, m)) { validStates.push(state); // Store the color configuration for this state const colors = []; let tempState = state; for (let i = 0; i < m; i++) { colors.push(tempState % 3); tempState = Math.floor(tempState / 3); } colorConfigs.set(state, colors); } } // Precompute valid transitions using color configurations const validTransitions = {}; for (const state1 of validStates) { validTransitions[state1] = []; const colors1 = colorConfigs.get(state1); for (const state2 of validStates) { const colors2 = colorConfigs.get(state2); let valid = true; for (let i = 0; i < m; i++) { if (colors1[i] === colors2[i]) { valid = false; break; } } if (valid) { validTransitions[state1].push(state2); } } } // Initialize DP array let dp = new Array(validStates.length).fill(1); // Fill DP array for (let j = 1; j < n; j++) { const newDp = new Array(validStates.length).fill(0); for (let i = 0; i < validStates.length; i++) { const state1 = validStates[i]; for (let k = 0; k < validTransitions[state1].length; k++) { const state2 = validTransitions[state1][k]; const idx = validStates.indexOf(state2); newDp[idx] = (newDp[idx] + dp[i]) % MOD; } } dp = newDp; } // Sum up the results let result = 0; for (let i = 0; i < validStates.length; i++) { result = (result + dp[i]) % MOD; } return result;} // Test casesconsole.log(colorTheGrid(1, 1)); // 3console.log(colorTheGrid(1, 2)); // 6console.log(colorTheGrid(5, 3)); // 580986
First, understand that we need to count the number of ways to paint an m × n grid with three colors such that no adjacent cells have the same color.
Generate all valid column states where no adjacent cells in the column have the same color.
For each valid column state, precompute all valid next states that can follow it (no horizontally adjacent cells have the same color).
Use dynamic programming to count the number of ways to paint the grid, considering one column at a time.
Optimize the space complexity by only storing the DP results for the current column.
Modify the code to implement an alternative approach and test it with the same examples.
Implement a function that solves the painting a grid problem using a different approach than shown above.
Handle the case where the grid is 1×1 (can be painted in 3 ways).
Handle the case where the grid has only one row (alternating colors).
Handle the case where the grid has only one column (alternating colors).