Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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‎

Lines changed: 75 additions & 91 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /