const permutation = (arr, selectNum) => {
let result = [];
if (selectNum === 1) return arr.map((v) => [v]);
arr.forEach((v, idx, arr) => {
const fixer = v;
const restArr = arr.filter((_, index) => index !== idx);
const permuationArr = permutation(restArr, selectNum - 1);
const combineFixer = permuationArr.map((v) => [fixer, ...v]);
result.push(...combineFixer);
});
return result;
};
const isMatchId = (ban, user) => {
for (let i=0; i<ban.length; i++) {
if (ban[i] === '*') continue;
if (ban[i] !== user[i]) return false;
}
return true;
};
const check = (banned_id, candidates) => {
for (let i=0; i<banned_id.length; i++) {
if (candidates[i].length !== banned_id[i].length) return false;
if (!isMatchId(banned_id[i], candidates[i])) return false;
}
return true;
};
function solution(user_id, banned_id) {
const answer = [];
const candidateUsers = permutation(user_id, banned_id.length);
for (const candidates of candidateUsers) {
if (check(banned_id, candidates)) {
const setCandidates = candidates.sort();
if (answer.includes(JSON.stringify(setCandidates))) continue;
answer.push(JSON.stringify(setCandidates));
}
}
return answer.length;
}
풀이의 핵심은
banned_id
배열의 길이만큼banned_id
와 매칭할 유저의 모든 순열을 만드는 것이다. (최악의 경우가 8!이기 때문에 완전탐색을 해도 ㄱㅊ하다)
const setCandidates = candidates.sort();
에서 정렬을 해준 이유는 ['frodo', 'crodo', 'abc123']
와 ['crodo', 'frodo', 'abc123']
를 같은 경우로 처리해줘야 하기 때문이다.