Skip to content

Commit 79a28ed

Browse files
author
hasibulislam999
committed
Cat and Mouse II problem solved
1 parent ca3f31d commit 79a28ed

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/**
2+
* Title: Cat and Mouse II
3+
* Description: Given a rows x cols matrix grid and two integers catJump and mouseJump, return true if Mouse can win the game if both Cat and Mouse play optimally, otherwise return false.
4+
* Author: Hasibul Islam
5+
* Date: 06/05/2023
6+
*/
7+
8+
/**
9+
* @param {string[]} grid
10+
* @param {number} catJump
11+
* @param {number} mouseJump
12+
* @return {boolean}
13+
*/
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
26+
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+
}
40+
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;
57+
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+
}
75+
}
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;
106+
}
107+
};
108+
109+
return dp(0, mouse_pos, cat_pos);
110+
}

0 commit comments

Comments
 (0)