2
* @param {string[]} grid5
var shortestPathAllKeys = function (grid) {6
const rows = grid.length,8
INF = Number.MAX_SAFE_INTEGER - 1;10
/* Find the locks and keys */13
for (let i = 0; i < rows; i++) {14
for (let j = 0; j < cols; j++) {15
let letter = grid[i][j];20
if (letter === "." || letter === "#") continue;21
if (letter >= "a") keyChars += letter;24
let lockChars = keyChars.toUpperCase();25
const combos = Math.pow(2, keyChars.length);30
for (let i = 0; i < keyChars.length; i++) {31
bitPos[keyChars[i]] = mask;32
unlocks[lockChars[i]] = mask;37
for (let i = 0; i < rows; i++) {39
for (let j = 0; j < cols; j++) dp[i][j] = Array(combos).fill(INF);41
dp[start[0]][start[1]][0] = 0;43
//console.log(bitPos, unlocks);45
const getNeighbors = function (r, c) {47
if (r > 0) neighbors.push([r - 1, c]);48
if (r < rows - 1) neighbors.push([r + 1, c]);49
if (c > 0) neighbors.push([r, c - 1]);50
if (c < cols - 1) neighbors.push([r, c + 1]);55
/**** SMUSH functions to "smush" through the various terrain ****/56
const smushWall = (r, c, prev) => false;57
const smushSpace = function (r, c, prev) {59
for (let i = 0; i < prev.length; i++) {60
if (dp[r][c][i] > prev[i] + 1) {61
dp[r][c][i] = prev[i] + 1;67
const smushKeyFunc = function (key) {68
let mask = bitPos[key];69
const smushKey = function (r, c, prev) {71
for (let i = 0; i < prev.length; i++) {72
if (dp[r][c][i | mask] > prev[i] + 1) {73
dp[r][c][i | mask] = prev[i] + 1;81
const smushLockFunc = function (key) {82
let mask = unlocks[key];83
const smushLock = function (r, c, prev) {85
for (let i = 0; i < prev.length; i++) {86
if ((i & mask) !== mask) continue;87
if (dp[r][c][i] > prev[i] + 1) {88
dp[r][c][i] = prev[i] + 1;96
let smush = { "#": smushWall, ".": smushSpace, "@": smushSpace };97
for (let i = 0; i < keyChars.length; i++) {98
smush[keyChars[i]] = smushKeyFunc(keyChars[i]);100
for (let i = 0; i < lockChars.length; i++) {101
smush[lockChars[i]] = smushLockFunc(lockChars[i]);106
while (buf.length > 0) {107
let next = new Set();108
for (let [r, c] of buf) {109
let neighbors = getNeighbors(r, c);110
for (let [nrow, ncol] of neighbors) {111
if (smush[grid[nrow][ncol]](nrow, ncol, dp[r][c])) {112
if (dp[nrow][ncol][dp[nrow][ncol].length - 1] < INF)115
dp[nrow][ncol][dp[nrow][ncol].length - 1]117
else next.add([nrow, ncol]);124
//console.log(bitPos);126
return minPath === INF ? -1 : minPath;