Skip to content

Commit a8cf3d0

Browse files
author
hasibulislam999
committed
Cat and Mouse II minified
1 parent 79a28ed commit a8cf3d0

File tree

1 file changed

+75
-91
lines changed

1 file changed

+75
-91
lines changed

Game Theory/1728_cat-and-mouse-ii.js

+75-91
Original file line numberDiff line numberDiff line change
@@ -11,100 +11,84 @@
1111
* @param {number} mouseJump
1212
* @return {boolean}
1313
*/
14-
function canMouseWin(grid, catJump, mouseJump) {
15-
const dirs = [
16-
[1, 0],
17-
[-1, 0],
18-
[0, 1],
19-
[0, -1],
20-
];
21-
const m = grid.length;
22-
const n = grid[0].length;
23-
let mouse_pos = null;
24-
let cat_pos = null;
25-
let available = 0; // available steps for mouse and cat
14+
var canMouseWin = function (A, maxC, maxM) {
15+
let n = A.length,
16+
m = A[0].length,
17+
seen = {},
18+
pos = [
19+
[0, 1],
20+
[0, -1],
21+
[1, 0],
22+
[-1, 0],
23+
],
24+
xM,
25+
yM,
26+
xC,
27+
yC,
28+
xF,
29+
yF;
30+
for (let i = 0; i < n; i++)
31+
for (let j = 0; j < m; j++)
32+
if (A[i][j] === "M") [xM, yM] = [i, j];
33+
else if (A[i][j] === "C") [xC, yC] = [i, j];
34+
else if (A[i][j] === "F") [xF, yF] = [i, j];
2635

27-
// Search the start pos of mouse and cat
28-
for (let i = 0; i < m; i++) {
29-
for (let j = 0; j < n; j++) {
30-
if (grid[i][j] !== "#") {
31-
available++;
32-
}
33-
if (grid[i][j] === "M") {
34-
mouse_pos = [i, j];
35-
} else if (grid[i][j] === "C") {
36-
cat_pos = [i, j];
37-
}
38-
}
39-
}
36+
let invalid = ([x, y]) =>
37+
x < 0 || x >= n || y < 0 || y >= m ? true : A[x][y] === "#";
4038

41-
const dp = function (turn, mouse_pos, cat_pos) {
42-
// if (turn === m * n * 2) {
43-
// We already search the whole grid (9372 ms 74.3 MB)
44-
if (turn === available * 2) {
45-
// We already search the whole touchable grid (5200 ms 57.5 MB)
46-
return false;
47-
}
48-
if (turn % 2 === 0) {
49-
// Mouse
50-
const [i, j] = mouse_pos;
51-
for (let [di, dj] of dirs) {
52-
for (let jump = 0; jump <= mouseJump; jump++) {
53-
// Note that we want to do range(mouseJump + 1) instead of range(1, mouseJump + 1)
54-
// considering the case that we can stay at the same position for next turn.
55-
const new_i = i + di * jump;
56-
const new_j = j + dj * jump;
39+
//returns whether the current player ( determined by level -odd/even) can win the game while on the current state
40+
let recursion = ([[xM, yM], [xC, yC]], level) => {
41+
let whoPlays = Boolean(level % 2),
42+
state = [
43+
[
44+
[xM, yM],
45+
[xC, yC],
46+
],
47+
level,
48+
].toString(),
49+
maxAllowable = whoPlays ? maxC : maxM;
50+
if (seen[state] === undefined) {
51+
//memoization
52+
//end states
53+
if ((xC === xF && yC === yF) || (xC === xM && yC === yM) || level >= 70)
54+
// level>=70 makes this pass
55+
return (seen[state] = whoPlays);
56+
if (xM === xF && yM === yF) return (seen[state] = !whoPlays);
57+
//try staying still first
58+
if (
59+
recursion(
60+
[
61+
[xM, yM],
62+
[xC, yC],
63+
],
64+
level + 1
65+
) === false
66+
)
67+
return (seen[state] = true);
68+
//then try moving
69+
for (let [dx, dy] of pos)
70+
for (let k = 1; k <= maxAllowable; k++) {
71+
let newState = whoPlays
72+
? [xC + dx * k, yC + dy * k]
73+
: [xM + dx * k, yM + dy * k];
74+
if (invalid(newState) || seen[state]) break;
5775
if (
58-
0 <= new_i &&
59-
new_i < m &&
60-
0 <= new_j &&
61-
new_j < n &&
62-
grid[new_i][new_j] !== "#"
63-
) {
64-
// Valid pos
65-
if (
66-
dp(turn + 1, [new_i, new_j], cat_pos) ||
67-
grid[new_i][new_j] === "F"
68-
) {
69-
return true;
70-
}
71-
} else {
72-
// Stop extending the jump since we cannot go further
73-
break;
74-
}
76+
recursion(
77+
whoPlays ? [[xM, yM], newState] : [newState, [xC, yC]],
78+
level + 1
79+
) === false
80+
)
81+
return (seen[state] = true);
7582
}
76-
}
77-
return false;
78-
} else {
79-
// Cat
80-
const [i, j] = cat_pos;
81-
for (let [di, dj] of dirs) {
82-
for (let jump = 0; jump <= catJump; jump++) {
83-
const new_i = i + di * jump;
84-
const new_j = j + dj * jump;
85-
if (
86-
0 <= new_i &&
87-
new_i < m &&
88-
0 <= new_j &&
89-
new_j < n &&
90-
grid[new_i][new_j] !== "#"
91-
) {
92-
if (
93-
!dp(turn + 1, mouse_pos, [new_i, new_j]) ||
94-
(new_i === mouse_pos[0] && new_j === mouse_pos[1]) ||
95-
grid[new_i][new_j] === "F"
96-
) {
97-
// This condition will also handle the case that the cat cannot jump through the mouse
98-
return false;
99-
}
100-
} else {
101-
break;
102-
}
103-
}
104-
}
105-
return true;
83+
seen[state] = false;
10684
}
85+
return seen[state];
10786
};
108-
109-
return dp(0, mouse_pos, cat_pos);
110-
}
87+
return recursion(
88+
[
89+
[xM, yM],
90+
[xC, yC],
91+
],
92+
0
93+
);
94+
};

0 commit comments

Comments
 (0)