Skip to content

Instantly share code, notes, and snippets.

@klauszhang
Created November 13, 2017 20:05
Show Gist options
  • Save klauszhang/7076676d590687803f819cad4b5106b9 to your computer and use it in GitHub Desktop.
Save klauszhang/7076676d590687803f819cad4b5106b9 to your computer and use it in GitHub Desktop.
the dic look up approach
function maxLength(digit) {
return Math.pow(8, digit) * 9;
}
const getDic = digit =>
Array.from(new Array(Math.pow(10, digit) - 1))
.map((_, idx) => idx + 1)
.filter(v => v >= Math.pow(10, digit - 1));
function random(max) {
return Math.floor(Math.random() * (max + 1));
}
function checkConsecutive(nPlus1, n) {
return nPlus1 - n !== 1;
}
function haveNoConsecutive(
arr,
isValid = true,
idx = 0
) {
if (!isValid) {
return false;
}
return idx === arr.length - 1
? isValid
: haveNoConsecutive(
arr,
checkConsecutive(arr[idx + 1], arr[idx]),
idx + 1
);
}
const patternArr = [
/11/,
/22/,
/33/,
/44/,
/55/,
/66/,
/77/,
/88/,
/99/,
/00/
];
function haveNoDuplicate(numberString, idx = 0) {
const pattern = patternArr[idx];
if (pattern.test(numberString)) {
return false;
}
if (idx === patternArr.length - 1) {
return true;
}
return haveNoDuplicate(numberString, idx + 1);
}
function getPin(digit) {
const internalDic = getDic(digit);
// console.log(internalDic);
return function ensureInShape(
dic = internalDic,
idx = 1
) {
const pin = dic[idx];
const stringPin = pin.toString();
let havDuplicate = !haveNoDuplicate(
stringPin
);
if (havDuplicate) {
return ensureInShape(
[
...dic.slice(0, idx),
...dic.slice(idx + 1)
],
random(dic.length - 2)
);
}
const haveConsecutive = !haveNoConsecutive(
stringPin
.split('')
.map(item => parseInt(item))
);
if (haveConsecutive) {
return ensureInShape(
[
...dic.slice(0, idx),
...dic.slice(idx + 1)
],
random(dic.length - 2)
);
}
return pin;
};
}
function pick(digit, count) {
const set = new Set();
const maxlen = maxLength(digit - 1);
if (count > maxlen) {
throw new Error(
`cannot have more than ${maxlen} combinations for ${digit} digit(s)`
);
}
const generator = getPin(digit);
return function recrusive() {
if (set.size === count) {
return set;
}
set.add(generator());
return recrusive();
};
}
module.exports = pick;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment