function nimber(matrix) {
var rect = [ 1, 2, 3, 4, 6, 7, 8, 12, 14, 15,
16, 17, 32, 34, 48, 51, 64, 68, 96, 102,
112, 119, 128, 136, 192, 204, 224, 238, 240, 255,
256, 272, 273, 512, 544, 546, 768, 816, 819, 1024,
1088, 1092, 1536, 1632, 1638, 1792, 1904, 1911, 2048, 2176,
2184, 3072, 3264, 3276, 3584, 3808, 3822, 3840, 4080, 4095,
4096, 4352, 4368, 4369, 8192, 8704, 8736, 8738,12288,13056,
13104,13107,16384,17408,17472,17476,24576,26112,26208,26214,
28672,30464,30576,30583,32768,34816,34944,34952,49152,52224,
52416,52428,57344,60928,61152,61166,61440,65280,65520,65535];
var memo = [0]; // nimber of empty matrix is 0
return nim(matrix);
function nim(current) {
if (memo.hasOwnProperty(current)) return memo[current]; // use memoized value
var exclude = []; // set of nimbers of reachable states
for (var i = 0; i < rect.length; i++) {
if ((current & rect[i]) == rect[i]) { // this rectangle is a valid move
var next = current & ~rect[i]; // remove rectangle
exclude[nim(next)] = true; // recurse and add nimber to set
}
}
return (memo[current] = mex(exclude)); // memoize this nimber
}
function mex(n) { // minimum excludant of nimber set
var m = 0;
while (n[m]) ++m;
return m;
}
}
document.write(nimber(65535)); // 0b1111111111111111 represents a filled 4x4 matrix
如果第一個玩家可以刪除整個矩陣,他/她是不是總是贏家? – IVlad
作爲一個算法(只是一個快速的想法),你會不會嘗試選擇剩餘模塊化2的最小操作?所以你的算法必須找到要移除的矩陣,所以爲了贏得遊戲,還有2個矩陣存在? – pandaadb
@IVlad玩家從'X'矩陣中選擇一個子矩陣並將其移除,所以一次只能移除一個子矩陣 –