각 banned_id
마다 충족하는 user_id
요소들을 찾아서 list
로 저장.
즉, [[a1, a2], [b1, b2, b3], ... ]
처럼 2차원 배열을 만든다.
모든 후보를 저장한 list
를 순회하면서 만들 수 있는 모든 조합을 계산.
이전에 저장한 것과 겹치는 경우는 무시한다.
function solution(user_id, banned_id) {
// 패턴을 매개변수로 받고, 패턴을 충족하는 user_id 요소들을 배열로 반환
const getter = (p) => {
return user_id.reduce((acc, nickname) => {
if (p.length !== nickname.length) return acc;
for (let i = 0; i < p.length; i++) {
if (p[i] !== nickname[i] && p[i] !== "*") return acc;
}
acc.push(nickname);
return acc;
}, []);
};
// 두 배열의 구성이 동일하다면 sort하고 join하면 똑같은 문자열이 될 것이다.
const isSame = (arr1, arr2) => arr1.sort().join("") === arr2.sort().join("");
// 새로 만든 arr가 list에 없는 구성의 배열인지 확인하는 함수
const check = (list, arr) => list.every((e) => !isSame(e, arr));
const dfs = (origin, result, list, depth) => {
if (depth >= banned_id.length) {
// list가 result에 없는 구성의 배열이면 push
check(result, list) && result.push(list);
return list;
}
for (let i = 0; i < origin[depth].length; i++) {
if (!list.includes(origin[depth][i])) {
dfs(origin, result, [...list, origin[depth][i]], depth + 1);
}
}
return result;
};
const list = banned_id.map(getter);
const combined = dfs(list, [], [], 0);
return combined.length;
}