diff --git a/calc.js b/calc.js index dee668f..b4dc1e0 100644 --- a/calc.js +++ b/calc.js @@ -1,233 +1,218 @@ -const blocks = [ - [ - [ - [1, 1], - [1, 1] - ] - ], - [ - [ - [2, 2, 2, 2] - ], - [ - [2], - [2], - [2], - [2] - ] - ], - [ - [ - [3, 3, 0], - [0, 3, 3] - ], - [ - [0, 3], - [3, 3], - [3, 0] - ] - ], - [ - [ - [0, 4, 4], - [4, 4, 0] - ], - [ - [4, 0], - [4, 4], - [0, 4] - ] - ], - [ - [ - [5, 0, 0], - [5, 5, 5] - ], - [ - [5, 5], - [5, 0], - [5, 0] - ], - [ - [5, 5, 5], - [0, 0, 5] - ], - [ - [0, 5], - [0, 5], - [5, 5] - ] - ], - [ - [ - [0, 0, 6], - [6, 6, 6] - ], - [ - [6, 6], - [0, 6], - [0, 6] - ], - [ - [6, 6, 6], - [6, 0, 0] - ], - [ - [6, 0], - [6, 0], - [6, 6] - ] - ], - [ - [ - [0, 7, 0], - [7, 7, 7] - ], - [ - [7, 7, 7], - [0, 7, 0] - ], - [ - [7, 0], - [7, 7], - [7, 0] - ], - [ - [0, 7], - [7, 7], - [0, 7] - ] - ], - [ - [ - [0, 8, 0], - [8, 8, 8], - [0, 8, 0] - ] - ], - [ - [ - [9] - ] - ], - [ - [ - [10, 10] - ], - [ - [10], - [10] - ] - ], - [ - [ - [11, 11], - [11, 0], - ], - [ - [11, 11], - [0, 11], - ], - [ - [0, 11], - [11, 11], - ], - [ - [11, 0], - [11, 11], - ], - ] -]; - -let m, n, a, l, res; - -function Solve(arr, num) { - res = []; - m = arr.length; - n = arr[0].length; - - a = new Array(m); - for (let i = 0; i < m; ++i) { - a[i] = arr[i].map(x => x); - } - - l = num.map(x => x); - - dfs(0); - - // Sort res by the number of distinct elements in each matrix, in descending order - // If the number of distinct elements is the same, sort by the highest number in l for each element used in A and B - res.sort((A, B) => { - let distinctA = new Set(A.flat()).size; - let distinctB = new Set(B.flat()).size; - - if (distinctA !== distinctB) { - return distinctB - distinctA; - } else { - let maxA = Math.max(...A.flat().map(x => l[x-1])); - let maxB = Math.max(...B.flat().map(x => l[x-1])); - return maxB - maxA; - } - }); - - return res; -} - -function canPlaceBlock(x, y, b, d) { - const pat = blocks[b][d]; - let offset = 0; - while (!pat[0][offset]) ++offset; - y -= offset; - if (y < 0) return false; - for (let i = 0; i < pat.length; ++i) { - for (let j = 0; j < pat[0].length; ++j) { - if (pat[i][j] && (x + i >= m || y + j >= n || a[x + i][y + j] !== -1)) return false; - } - } - return true; -} - -function placeBlock(x, y, b, d, v) { - const pat = blocks[b][d]; - let offset = 0; - while (!pat[0][offset]) ++offset; - y -= offset; - for (let i = 0; i < pat.length; ++i) { - for (let j = 0; j < pat[0].length; ++j) { - if (pat[i][j]) a[x + i][y + j] = v; - } - } -} - -function dfs(p) { - if (p === m * n) { - const x = new Array(m); - for (let i = 0; i < m; ++i) { - x[i] = a[i].map(x => x); - } - res.push(x); - if (res.length >= 10000) { - alert('方案数太多,仅计算前一万种。减少一些方块吧~'); - return true; - } - return false; - } - const x = Math.floor(p / n), y = p % n; - if (a[x][y] !== -1) { - if (dfs(p + 1)) return true; - return false; - } - for (let b = 0; b < blocks.length; ++b) { - if (!l[b]) continue; - for (let d = 0; d < blocks[b].length; ++d) { - if (!canPlaceBlock(x, y, b, d)) continue; - placeBlock(x, y, b, d, b + 1); - --l[b]; - if (dfs(p + 1)) return true; - ++l[b]; - placeBlock(x, y, b, d, -1); - } - } - return false; -} - +const blocks = [ + [ + [ + [1, 1], + [1, 1] + ] + ], + [ + [ + [2, 2, 2, 2] + ], + [ + [2], + [2], + [2], + [2] + ] + ], + [ + [ + [3, 3, 0], + [0, 3, 3] + ], + [ + [0, 3], + [3, 3], + [3, 0] + ] + ], + [ + [ + [0, 4, 4], + [4, 4, 0] + ], + [ + [4, 0], + [4, 4], + [0, 4] + ] + ], + [ + [ + [5, 0, 0], + [5, 5, 5] + ], + [ + [5, 5], + [5, 0], + [5, 0] + ], + [ + [5, 5, 5], + [0, 0, 5] + ], + [ + [0, 5], + [0, 5], + [5, 5] + ] + ], + [ + [ + [0, 0, 6], + [6, 6, 6] + ], + [ + [6, 6], + [0, 6], + [0, 6] + ], + [ + [6, 6, 6], + [6, 0, 0] + ], + [ + [6, 0], + [6, 0], + [6, 6] + ] + ], + [ + [ + [0, 7, 0], + [7, 7, 7] + ], + [ + [7, 7, 7], + [0, 7, 0] + ], + [ + [7, 0], + [7, 7], + [7, 0] + ], + [ + [0, 7], + [7, 7], + [0, 7] + ] + ], + [ + [ + [0, 8, 0], + [8, 8, 8], + [0, 8, 0] + ] + ], + [ + [ + [9] + ] + ], + [ + [ + [10, 10] + ], + [ + [10], + [10] + ] + ], + [ + [ + [11, 11], + [11, 0], + ], + [ + [11, 11], + [0, 11], + ], + [ + [0, 11], + [11, 11], + ], + [ + [11, 0], + [11, 11], + ], + ] +]; + +let m, n, a, l, res; + +function Solve(arr, num) { + res = []; + m = arr.length; + n = arr[0].length; + + a = new Array(m); + for (let i = 0; i < m; ++i) { + a[i] = arr[i].map(x => x); + } + + l = num.map(x => x); + + dfs(0); + + return res; +} + +function canPlaceBlock(x, y, b, d) { + const pat = blocks[b][d]; + let offset = 0; + while (!pat[0][offset]) ++offset; + y -= offset; + if (y < 0) return false; + for (let i = 0; i < pat.length; ++i) { + for (let j = 0; j < pat[0].length; ++j) { + if (pat[i][j] && (x + i >= m || y + j >= n || a[x + i][y + j] !== -1)) return false; + } + } + return true; +} + +function placeBlock(x, y, b, d, v) { + const pat = blocks[b][d]; + let offset = 0; + while (!pat[0][offset]) ++offset; + y -= offset; + for (let i = 0; i < pat.length; ++i) { + for (let j = 0; j < pat[0].length; ++j) { + if (pat[i][j]) a[x + i][y + j] = v; + } + } +} + +function dfs(p) { + if (p === m * n) { + const x = new Array(m); + for (let i = 0; i < m; ++i) { + x[i] = a[i].map(x => x); + } + res.push(x); + if (res.length >= 10000) { + alert('方案数太多,仅计算前一万种。减少一些方块吧~'); + return true; + } + return false; + } + const x = Math.floor(p / n), y = p % n; + if (a[x][y] !== -1) { + if (dfs(p + 1)) return true; + return false; + } + for (let b = 0; b < blocks.length; ++b) { + if (!l[b]) continue; + for (let d = 0; d < blocks[b].length; ++d) { + if (!canPlaceBlock(x, y, b, d)) continue; + placeBlock(x, y, b, d, b + 1); + --l[b]; + if (dfs(p + 1)) return true; + ++l[b]; + placeBlock(x, y, b, d, -1); + } + } + return false; +} + diff --git a/calc.min.js b/calc.min.js index 5b02045..85b853f 100644 --- a/calc.min.js +++ b/calc.min.js @@ -1 +1 @@ -const blocks=[[[[1,1],[1,1]]],[[[2,2,2,2]],[[2],[2],[2],[2]]],[[[3,3,0],[0,3,3]],[[0,3],[3,3],[3,0]]],[[[0,4,4],[4,4,0]],[[4,0],[4,4],[0,4]]],[[[5,0,0],[5,5,5]],[[5,5],[5,0],[5,0]],[[5,5,5],[0,0,5]],[[0,5],[0,5],[5,5]]],[[[0,0,6],[6,6,6]],[[6,6],[0,6],[0,6]],[[6,6,6],[6,0,0]],[[6,0],[6,0],[6,6]]],[[[0,7,0],[7,7,7]],[[7,7,7],[0,7,0]],[[7,0],[7,7],[7,0]],[[0,7],[7,7],[0,7]]],[[[0,8,0],[8,8,8],[0,8,0]]],[[[9]]],[[[10,10]],[[10],[10]]],[[[11,11],[11,0]],[[11,11],[0,11]],[[0,11],[11,11]],[[11,0],[11,11]]]];let m,n,a,l,res;function Solve(e,t){res=[],m=e.length,n=e[0].length,a=new Array(m);for(let t=0;te));return l=t.map((e=>e)),dfs(0),res.sort(((e,t)=>{let n=new Set(e.flat()).size,r=new Set(t.flat()).size;if(n!==r)return r-n;{let n=Math.max(...e.flat().map((e=>l[e-1])));return Math.max(...t.flat().map((e=>l[e-1])))-n}})),res}function canPlaceBlock(e,t,l,r){const o=blocks[l][r];let f=0;for(;!o[0][f];)++f;if((t-=f)<0)return!1;for(let l=0;l=m||t+r>=n||-1!==a[e+l][t+r]))return!1;return!0}function placeBlock(e,t,l,n,r){const o=blocks[l][n];let f=0;for(;!o[0][f];)++f;t-=f;for(let l=0;le));return res.push(e),res.length>=1e4&&(alert("方案数太多,仅计算前一万种。减少一些方块吧~"),!0)}const t=Math.floor(e/n),r=e%n;if(-1!==a[t][r])return!!dfs(e+1);for(let n=0;nb);l=d.map(c=>c);dfs(0);return res}function canPlaceBlock(e,d,c,b){c=blocks[c][b];for(b=0;!c[0][b];)++b;d-=b;if(0>d)return!1;for(b=0;b=m||d+f>=n||-1!==a[e+b][d+f]))return!1;return!0}function placeBlock(e,d,c,b,f){c=blocks[c][b];for(b=0;!c[0][b];)++b;d-=b;for(b=0;bb);res.push(e);return 1E4<=res.length?(alert("\u65b9\u6848\u6570\u592a\u591a\uff0c\u4ec5\u8ba1\u7b97\u524d\u4e00\u4e07\u79cd\u3002\u51cf\u5c11\u4e00\u4e9b\u65b9\u5757\u5427~"),!0):!1}d=Math.floor(e/n);const c=e%n;if(-1!==a[d][c])return dfs(e+1)?!0:!1;for(let b=0;b - - - - - - 尘白禁区信源研析 - - - - - - Bilibili 方形的块状代码 -
-

行数:

-

列数:

- -

红色表示需要摆放的格子,白色表示这里没有格子,点击切换

-
-
-
-
-

方块{{ i + 1 }}个数:

- -
-
-

方案数:{{ res.length }}

-
-
-

当前展示方案:{{ now + 1 }} / {{ res.length }}

- - -
-
{{ c }}
-
-
-
- - - - - \ No newline at end of file + + + + + + + 尘白禁区信源研析 + + + + + + Bilibili 方形的块状代码 +
+

行数:

+

列数:

+ +

红色表示需要摆放的格子,白色表示这里没有格子,点击切换

+
+
+
+
+

方块{{ i + 1 }}个数:

+ +
+
+

方案数:{{ res.length }}

+
+
+

当前展示方案:{{ now + 1 }} / {{ res.length }}

+ + +
+
{{ c }}
+
+
+
+ + + + +