function fn(map = [], ops = [], m, n) {
let body = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (map[i][j] === 'H') {
body = [{
x: j,
y: i,
}];
break;
}
}
}
const opsMap = {
"U": {
x: 0,
y: -1,
},
"L": {
x: -1,
y: 0,
},
"D": {
y: 1,
x: 0,
},
"R": {
x: 1,
y: 0,
}
}
let prevCmd = ops[0];
for (let i = 0; i < ops.length; i++) {
const cmd = ops[i];
if (opsMap[cmd]) {
prevCmd = cmd;
} else {
if (cmd === "G" && prevCmd) {
const {x, y} = opsMap[prevCmd];
const newHead = {
x: body[0].x + x,
y: body[0].y + y,
}
let newBody = [...body];
if (!isValidHead(newHead)) {
return body.length
}
newBody.unshift(newHead);
if (map[newHead.y][newHead.x] === 'F') {
map[newHead.y][newHead.x] = "E";
} else {
newBody.pop();
}
if (isTouch(newHead, newBody)) {
return body.length;
}
body = newBody;
}
}
}
function isValidHead(newHead) {
const {x, y} = newHead;
if (x < 0 || y < 0 || x > n - 1 || y > m - 1) {
return false;
}
return true;
}
function isTouch(newHead, newBody) {
const {x, y} = newHead;
for (let {x: cx, y: cy} of newBody.slice(1)) {
if (x === cx && cy===y) {
return true;
}
}
return false
}
return body.length
}
console.log(fn(
[
['F', 'F', 'F', 'F', 'F'],
['F', 'F', 'F', 'F', 'F'],
['F', 'F', 'F', 'F', 'H'],
['F', 'F', 'F', 'F', 'F'],
['F', 'F', 'F', 'F', 'F'],
],
['U', 'G', 'G', 'G'],
5,
5
))
console.log(fn(
[
['F', 'F', 'F', 'F', 'F'],
['F', 'F', 'F', 'F', 'F'],
['F', 'F', 'F', 'F', 'H'],
['F', 'F', 'F', 'F', 'F'],
['F', 'F', 'F', 'F', 'F'],
],
['L', 'G', 'G', 'G', 'D', 'G', 'R', 'G', 'G', 'G', 'U', 'G'],
5,
5
))
console.log(fn(
[
['F', 'F', 'F'],
['F', 'F', 'H'],
['E', 'F', 'E'],
],
['D', 'G', 'G'],
3,
3
))