😈[プログラマー]不良ユーザー



問題の説明
開発チーム内で開発活動を担当していた「無知」は、最近行われたカカの表情活動で異常な方法で当選しようとした応募者を発見した.これらの応募者を単独で集め、불량 사용자の名義でリストを作成し、当選者代表の「専門家」に転送して、当選処理時に排除したいと思います.プライバシーを保護するために、ユーザーの特定のアイデンティティを「」文字で隠し、送信します.1文字に1つの「」文字が使用され、各IDには少なくとも1つの「*」文字が使用されます.
「無知」と「専門」は、不良ユーザーリストにマッピングされた応募者IDを제재 아이디と呼ぶことにした.
たとえば、イベントに対して次の完全なユーザーIDリストが指定されている場合:
応募者ID frodofradicrodobabc 123 frodoc
不良ユーザーIDリストがある場合は、次の操作を行います.
不良ユーザーfr*d*abc 1**
次の2つの場合、不良ユーザーにマッピングし、当選から除外するトピックIDリストが必要になる場合があります.
題材id frodoadabc 123
題材id frodoadabc 123
アクティブ応募者IDリスト付きの配列user idと不良ユーザIDリストを含む配列無効idをパラメータとする場合、solution関数を完了し、当選中の題材IDリストを除外するためにいくつかの場合に発生する可能性のある数を返します.

[制限]

  • user id配列のサイズは8を超えない.
  • user id配列の各要素の値は、1または8未満の長さの文字列です.
    -要求されたユーザIDは重複しません.
    -ユーザーIDはアルファベット小文字と数字で構成されています.
  • で無効になっているid配列のサイズはuser id配列のサイズ以下です.
  • で無効になっているid配列の各要素の値は、1または8未満の長さの文字列です.
    -不正なユーザーIDは、小文字、数字、およびマスキング用の文字""のみで構成されます.
    -不良ユーザーIDには1文字以上の「」が含まれています.
    -1人の不良ユーザのIDが1人の応募者のIDに相当し、同一の応募者のIDが重複し、制裁IDリストには入らない.
  • トピックのIDリストを取得した場合、これらのIDの順序にかかわらず、IDリストの内容が同じであれば、それを同一と見なし、一括して計算することができる.
  • [I/O例]


    user_idbanned_idresult["frodo", "fradi", "crodo", "abc123", "frodoc"]["frd", "abc1**"]2["frodo", "fradi", "crodo", "abc123", "frodoc"]["rodo", "rodo", "**"]2["frodo", "fradi", "crodo", "abc123", "frodoc"]["frd", "*rodo", "**", "**"]3
    I/O例説明
    I/O例#1
    問題の説明.
    I/O例#2
    次の2つのケースがあります.
    題材ID frodocrodobabc 123
    題材ID frodocrodobabc 123
    I/O例#3
    3つのケースがあります.
    題材ID frodocrodobabc 123 frodoc
    題材id fradicrodobabc 123 frodoc
    題材id fradifrodoabc 123 frodoc

    私の答え

    function solution(user_id, banned_id) {
        // 배열의 각 요소 별 밴 당할 수 있는 이용자
        const can = banned_id.map(banned => user_id.filter((user) => {
            if(banned.length !== user.length) return false
            
            for(let i = 0 ; i < banned_id.length ; i++) {
                if(banned[i] !== '*' && banned[i] !== user[i]) return false
            }
            return true
        }))
        
        // 정답 리스트
        const ansList = {}
        
        const dfs = (idx = 0, already = []) => {
            // 경우의 수 수와 같아졌다면
            if(idx === can.length) {
                // 배열을 정렬하고 key에 맞는 값을 true로 선언
                already.sort()
                ansList[already.join('')] = true
                return 
            }
            
            // 아직 방문하지 않았다면 방문한 배열에 삽입하고 인덱스를 1 높임
            can[idx].forEach(item => {
                if(!already.includes(item)) {
                    dfs(idx+1, [...already, item])
                }
            })
        }
        dfs()
        // 정리된 오브젝트의 키 값은 고유하므로 고유 값의 길이를 return 
        return Object.keys(ansList).length
    }