The observed PIN
链接
题目
好啦,侦探,我们的一个同事已经成功观察到我们的目标人物——强盗Robby。我们跟踪他到了一个秘密仓库,我们认为这里能找到所有他偷的东西。仓库的门用的是一个电子密码锁。不幸的是我们的间谍不确定他看到Robby输入的密码。
密码盘是下面这种布局:
┌───┬───┬───┐
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┼───┼───┘
│ 0 │
└───┘
他记录的密码是1357
,但他还说他看到的每个数字也可能是另一个相邻数字(水平或者垂直,但不是斜角)。比如说1
可能是2
或者4
。5
可能是2
,4
,6
或者8
。
他还提到,他了解这种类型的锁。你可以输入无限次数的错误密码,它们不会把系统锁定或者发出警报。这也是我们可以尝试各种可能性的原因。
你能否帮助我们找出所有的变化?它最好是一个函数,为一个观察到的长度为1到8个数字的密码所产生的变化组成的数组。我们可以把函数命名为getPINs
。但请注意所有密码都为字符串,因为密码可能由’0’开头。
思路
function getPINs(observed) {
return combineArr(observed.split(""));
function po(a) {
switch(a) {
case "1":
return ["2", "4", '1'];
break;
case "2":
return ["1", "3", "5", '2'];
break;
case '3':
return ['2', '6', '3'];
break;
case '4':
return ['1', '5', '7', '4'];
break;
case '5':
return ['2', '4', '6', '8', '5'];
break;
case '6':
return ['3', '5', '9', '6'];
break;
case '7':
return ['4', '8', '7'];
break;
case '8':
return ['5', '7', '9', '0', '8'];
break;
case '9':
return ['6', '8', '9'];
break;
case '0':
return ['8', '0'];
break;
}
}
function combineArr(arr) {
if (arr.length == 1) {
return po(arr[0]);
} else if (arr.length == 2) {
var arr1 = po(arr[0]);
var arr2 = po(arr[1]);
var result = [];
for (var i=0; i<arr1.length; i++) {
for (var j=0; j<arr2.length; j++) {
result.push(arr1[i] + arr2[j]);
}
}
return result;
} else if (arr.length > 2) {
var arr3 = po(arr[0]);
arr.shift()
var arr4 = combineArr(arr);
var result = [];
for (var m=0; m<arr3.length; m++) {
for (var n=0; n<arr4.length; n++) {
result.push(arr3[m] + arr4[n]);
}
}
return result;
}
}
}
Best Practice
function getPINs(observed) {
var adjacent = [
/* 0 */ [0, 8],
/* 1 */ [1, 2, 4],
/* 2 */ [1, 2, 3, 5],
/* 3 */ [2, 3, 6],
/* 4 */ [1, 4, 5, 7],
/* 5 */ [2, 4, 5, 6, 8],
/* 6 */ [3, 5, 6, 9],
/* 7 */ [4, 7, 8],
/* 8 */ [5, 7, 8, 9, 0],
/* 9 */ [6, 8, 9]
];
return observed
.split('')
.map(function(d) { return adjacent[d|0]; })
.reduce(function(pa, da) {
return da.reduce(function(pv, d) {
return pv.concat(pa.map(function(p) {
return '' + p + d;
}));
}, []);
}, ['']);
}
function getPINs(observed) {
return observed.split('')
.map( t => ({
'0': [ '0', '8' ],
'1': [ '1', '2', '4' ],
'2': [ '1', '2', '3', '5' ],
'3': [ '2', '3', '6' ],
'4': [ '1', '4', '5', '7' ],
'5': [ '2', '4', '5', '6', '8' ],
'6': [ '3', '5', '6', '9' ],
'7': [ '4', '7', '8' ],
'8': [ '5', '7', '8', '9', '0' ],
'9': [ '6', '8', '9' ]
}[t]))
.reduce((pre, cur)=> [].concat.apply([], pre.map(t => cur.map(g => t + g))));
}
function mixNMatch(add, addTo) {
var out = [];
add.forEach(function(v, i) {addTo.forEach(function(w, j) {out.push(v + w);});});
return out;
}
function getPINs(observed) {
var map = {1:['1','2','4'], 2:['1','2','3','5'], 3:['2','3','6'], 4:['1','4','5','7'], 5:['2','4','5','6','8'],
6:['3','5','6','9'], 7:['4','7','8'], 8:['5','7','8','9','0'], 9:['6','8','9'], 0:['8','0']};
return observed.length == 1 ? map[observed[0]] : mixNMatch(map[observed[0]], getPINs(observed.slice(1)));
}